Skip to content

Commit 2806d1a

Browse files
committed
feature: add blog website
1 parent 3962ec4 commit 2806d1a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

67 files changed

+15021
-0
lines changed

website/.gitignore

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2+
3+
# dependencies
4+
/node_modules
5+
/.pnp
6+
.pnp.*
7+
.yarn/*
8+
!.yarn/patches
9+
!.yarn/plugins
10+
!.yarn/releases
11+
!.yarn/versions
12+
13+
# testing
14+
/coverage
15+
16+
# next.js
17+
/.next/
18+
/out/
19+
20+
# production
21+
/build
22+
23+
# misc
24+
.DS_Store
25+
*.pem
26+
27+
# debug
28+
npm-debug.log*
29+
yarn-debug.log*
30+
yarn-error.log*
31+
.pnpm-debug.log*
32+
33+
# env files (can opt-in for committing if needed)
34+
.env*
35+
36+
# vercel
37+
.vercel
38+
39+
# typescript
40+
*.tsbuildinfo
41+
next-env.d.ts

website/README.md

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
# Tech Notes Hub Website
2+
3+
A modern blog website built with Next.js, Tailwind CSS, shadcn UI, and i18n support for multilingual content (Vietnamese and English).
4+
5+
## Features
6+
7+
- **Modern UI**: Clean, minimal design with Tailwind CSS and shadcn UI components
8+
- **Bilingual Support**: Full i18n integration with Vietnamese and English translations
9+
- **Blog System**: Complete blog functionality with Markdown content rendering
10+
- **Dark/Light Mode**: Theme switching with system preference detection
11+
- **SEO Optimized**: Complete SEO setup with meta tags, OpenGraph data, dynamic sitemap.xml, robots.txt, structured metadata, canonical URLs and language alternates
12+
- **Responsive Design**: Mobile-first approach, works on all devices
13+
14+
## Tech Stack
15+
16+
- [Next.js 14](https://nextjs.org/) - React framework
17+
- [Tailwind CSS](https://tailwindcss.com/) - Utility-first CSS framework
18+
- [shadcn UI](https://ui.shadcn.com/) - UI component library
19+
- [React Markdown](https://github.com/remarkjs/react-markdown) - Markdown renderer
20+
- [i18n](https://nextjs.org/docs/app/building-your-application/routing/internationalization) - Internationalization
21+
- [next-themes](https://github.com/pacocoursey/next-themes) - Theme management
22+
23+
## Getting Started
24+
25+
### Prerequisites
26+
27+
- Node.js 18.17 or later
28+
- npm or yarn
29+
30+
### Installation
31+
32+
1. Clone the repository
33+
```bash
34+
git clone <repository-url>
35+
cd website
36+
```
37+
38+
2. Install dependencies
39+
```bash
40+
npm install
41+
# or
42+
yarn install
43+
```
44+
45+
3. Run the development server
46+
```bash
47+
npm run dev
48+
# or
49+
yarn dev
50+
```
51+
52+
4. Open [http://localhost:3000](http://localhost:3000) with your browser to see the result
53+
54+
## Project Structure
55+
56+
```
57+
website/
58+
├── public/ # Static assets
59+
├── src/
60+
│ ├── app/ # App router pages
61+
│ │ ├── [locale]/ # Locale-specific routes
62+
│ │ │ ├── blog/ # Blog pages
63+
│ │ │ ├── about/ # About page
64+
│ │ ├── components/ # React components
65+
│ │ │ ├── ui/ # UI components (shadcn)
66+
│ │ │ ├── layout/ # Layout components
67+
│ │ │ ├── blog/ # Blog-specific components
68+
│ │ ├── data/ # Data sources
69+
│ │ │ ├── i18n/ # Translation files
70+
│ │ │ ├── blog-posts.ts # Blog post data
71+
│ │ ├── lib/ # Utility functions
72+
│ │ │ ├── i18n/ # i18n utilities
73+
│ │ │ ├── utils.ts # Helper functions
74+
│ │ │ ├── types.ts # TypeScript types
75+
├── next.config.ts # Next.js configuration
76+
├── tailwind.config.js # Tailwind CSS configuration
77+
```
78+
79+
## Adding Content
80+
81+
### Blog Posts
82+
83+
To add new blog posts, edit the `src/data/blog-posts.ts` file. Each post should follow the BlogPost interface defined in `src/lib/types.ts`.
84+
85+
### Translations
86+
87+
Add or edit translations in the following files:
88+
- `src/data/i18n/en/common.json` - English translations
89+
- `src/data/i18n/vi/common.json` - Vietnamese translations
90+
91+
## Deployment
92+
93+
### Build for Production
94+
95+
```bash
96+
npm run build
97+
# or
98+
yarn build
99+
```
100+
101+
### Deploy to Vercel
102+
103+
The easiest way to deploy the application is to use the [Vercel Platform](https://vercel.com/).
104+
105+
1. Push your code to a Git repository (GitHub, GitLab, or Bitbucket)
106+
2. Import the project to Vercel
107+
3. Vercel will detect Next.js and configure the build settings automatically
108+
4. Click "Deploy"
109+
110+
### Other Deployment Options
111+
112+
You can also deploy to other platforms like Netlify, AWS Amplify, or traditional hosting with a Node.js server.
113+
114+
For static export:
115+
116+
```bash
117+
npm run build
118+
npm run export
119+
```
120+
121+
This will generate a static version of the site in the `out` directory that can be served by any static hosting service.
122+
123+
## License
124+
125+
This project is licensed under the MIT License - see the LICENSE file for details.

website/WEBSITE_README.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Tech Notes Hub Blog Website
2+
3+
This is the blog website component of the Tech Notes Hub project. The website is built using Next.js, Tailwind CSS, shadcn UI, and i18n support for multilingual content (Vietnamese and English).
4+
5+
## Overview
6+
7+
The blog website serves as a frontend for displaying technical content and notes from the Tech Notes Hub repository. It provides a modern, responsive interface for users to browse and read technical articles.
8+
9+
## Getting Started
10+
11+
The blog website is located in the `/website` directory. To start working with it:
12+
13+
```bash
14+
cd website
15+
npm install
16+
npm run dev
17+
```
18+
19+
Open [http://localhost:3000](http://localhost:3000) to view the site in your browser.
20+
21+
## Features
22+
23+
- Modern UI built with Next.js and Tailwind CSS
24+
- Bilingual support (Vietnamese and English)
25+
- Dark/Light mode
26+
- Responsive design
27+
- SEO optimized
28+
- Markdown content rendering
29+
30+
## Documentation
31+
32+
For detailed information about the blog website, including setup instructions, project structure, and deployment guidelines, please refer to the [Website README](/website/README.md) in the website directory.

website/components.json

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"$schema": "https://ui.shadcn.com/schema.json",
3+
"style": "new-york",
4+
"rsc": true,
5+
"tsx": true,
6+
"tailwind": {
7+
"config": "",
8+
"css": "src/app/globals.css",
9+
"baseColor": "neutral",
10+
"cssVariables": true,
11+
"prefix": ""
12+
},
13+
"aliases": {
14+
"components": "@/components",
15+
"utils": "@/lib/utils",
16+
"ui": "@/components/ui",
17+
"lib": "@/lib",
18+
"hooks": "@/hooks"
19+
},
20+
"iconLibrary": "lucide"
21+
}

website/eslint.config.mjs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { dirname } from "path";
2+
import { fileURLToPath } from "url";
3+
import { FlatCompat } from "@eslint/eslintrc";
4+
5+
const __filename = fileURLToPath(import.meta.url);
6+
const __dirname = dirname(__filename);
7+
8+
const compat = new FlatCompat({
9+
baseDirectory: __dirname,
10+
});
11+
12+
const eslintConfig = [
13+
...compat.extends("next/core-web-vitals", "next/typescript"),
14+
];
15+
16+
export default eslintConfig;

website/next-seo.config.js

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// Default SEO configuration
2+
const defaultSEOConfig = {
3+
titleTemplate: '%s - Tech Notes Hub',
4+
defaultTitle: 'Tech Notes Hub',
5+
description: 'A collection of tech notes, code snippets, and technical guides for developers',
6+
canonical: 'https://technotes.example.com',
7+
openGraph: {
8+
type: 'website',
9+
locale: 'vi_VN',
10+
url: 'https://technotes.example.com',
11+
siteName: 'Tech Notes Hub',
12+
title: 'Tech Notes Hub',
13+
description: 'A collection of tech notes, code snippets, and technical guides for developers',
14+
images: [
15+
{
16+
url: 'https://technotes.example.com/og-image.jpg',
17+
width: 1200,
18+
height: 630,
19+
alt: 'Tech Notes Hub',
20+
},
21+
],
22+
},
23+
twitter: {
24+
handle: '@technotes',
25+
site: '@technotes',
26+
cardType: 'summary_large_image',
27+
},
28+
additionalMetaTags: [
29+
{
30+
name: 'viewport',
31+
content: 'width=device-width, initial-scale=1',
32+
},
33+
{
34+
name: 'author',
35+
content: 'Tech Notes Team',
36+
},
37+
{
38+
name: 'keywords',
39+
content: 'tech, programming, algorithms, design patterns, databases, devops, linux, system design, testing',
40+
},
41+
],
42+
additionalLinkTags: [
43+
{
44+
rel: 'icon',
45+
href: '/favicon.ico',
46+
},
47+
{
48+
rel: 'apple-touch-icon',
49+
href: '/apple-touch-icon.png',
50+
sizes: '180x180',
51+
},
52+
{
53+
rel: 'manifest',
54+
href: '/site.webmanifest',
55+
},
56+
],
57+
};
58+
59+
export default defaultSEOConfig;

website/next.config.js

Whitespace-only changes.

website/next.config.ts

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import type { NextConfig } from "next";
2+
3+
const nextConfig: NextConfig = {
4+
reactStrictMode: true,
5+
swcMinify: true,
6+
images: {
7+
domains: ['technotes.example.com'],
8+
},
9+
// Configure experimental features if needed
10+
experimental: {
11+
// Add experimental features here when required
12+
},
13+
// Add custom headers for security and caching
14+
async headers() {
15+
return [
16+
{
17+
source: '/(.*)',
18+
headers: [
19+
{
20+
key: 'X-DNS-Prefetch-Control',
21+
value: 'on',
22+
},
23+
{
24+
key: 'X-XSS-Protection',
25+
value: '1; mode=block',
26+
},
27+
{
28+
key: 'X-Content-Type-Options',
29+
value: 'nosniff',
30+
},
31+
{
32+
key: 'Referrer-Policy',
33+
value: 'strict-origin-when-cross-origin',
34+
},
35+
],
36+
},
37+
{
38+
// Apply caching headers for static assets
39+
source: '/(.*).(jpg|jpeg|png|gif|webp|svg|ico)',
40+
headers: [
41+
{
42+
key: 'Cache-Control',
43+
value: 'public, max-age=31536000, immutable',
44+
}
45+
],
46+
},
47+
];
48+
},
49+
// Redirect from root to default locale
50+
async redirects() {
51+
return [
52+
{
53+
source: '/',
54+
destination: '/en',
55+
permanent: true,
56+
},
57+
];
58+
},
59+
};
60+
61+
export default nextConfig;

0 commit comments

Comments
 (0)