- Published on
Next.js Blog Project - Advanced Study
- Authors

- Name
- Kto
Introduction
引言
本篇博客基于 Next.js Starter Blog 项目进行二次开发的实践经验分享。 This blog post shares practical experience from secondary development based on the Next.js Starter Blog project.
这个博客模板采用了现代化的技术栈,包括 Next.js App Router、Tailwind CSS、Contentlayer(MDX 处理)、Framer Motion 等。 This blog template uses a modern tech stack including Next.js App Router, Tailwind CSS, Contentlayer (MDX processing), Framer Motion, etc.
本文将深入介绍如何基于这个模板进行个性化定制,涵盖组件开发、样式系统、性能优化等多个方面。 This article will深入介绍 how to customize this template, covering component development, style systems, performance optimization, and more.
一、如何引入图片 | I. How to Import Images
方式一:使用本地图片 | Method 1: Using Local Images
将图片放置在 public/ 目录下,然后通过 Image 组件引用: Place images in the public/ directory and reference them via the Image component:
import Image from '@/components/Image'
// 直接使用
// Use directly
;<Image src="/images/your-image.png" alt="描述文字" width={800} height={400} />
方式二:使用远程图片 | Method 2: Using Remote Images
首先需要在 next.config.js 中配置允许的图片域名: First, configure allowed image domains in next.config.js:
// next.config.js
module.exports = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'example.com', // 替换为你的图片域名
pathname: '/images/**',
},
// Replace with your image domain
],
// 图片优化配置
// Image optimization configuration
deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
formats: ['image/webp', 'image/avif'],
},
}
然后在 MDX 文件中使用: Then use in MDX files:

或使用组件: Or use component:
<Image
src="https://example.com/image.png"
alt="描述"
width={800}
height={400}
priority // 首屏图片优先加载
/>
// Prioritize loading for above-fold images
响应式图片处理 | Responsive Image Handling
使用 sizes 属性实现响应式图片: Use sizes property for responsive images:
<Image
src="/images/hero.jpg"
alt="Hero Image"
fill
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
style={{ objectFit: 'cover' }}
/>
图片占位符和模糊效果 | Image Placeholder and Blur Effect
实现图片加载时的模糊占位效果: Implement blur placeholder effect during image loading:
<Image
src="/images/large.jpg"
alt="大图"
width={1200}
height={600}
placeholder="blur"
blurDataURL="data:image/jpeg;base64,/9j/4AAQSkZJRg..."
/>
图片懒加载策略 | Image Lazy Loading Strategy
import Image from 'next/image'
export default function Gallery() {
return (
<div className="grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3">
{[...Array(9)].map((_, i) => (
<Image
key={i}
src={`/images/image-${i}.jpg`}
alt={`Gallery image ${i}`}
width={400}
height={300}
loading="lazy" // 懒加载
// Lazy load
// 非首屏图片设置 loading="lazy"
// Set loading="lazy" for non-above-fold images
/>
))}
</div>
)
}
二、如何修改样式 | II. How to Modify Styles
全局样式修改 | Global Style Modification
项目使用 Tailwind CSS 作为样式框架。全局样式文件位于 css/tailwind.css。 The project uses Tailwind CSS as the style framework. Global styles are in css/tailwind.css.
/* css/tailwind.css */
/* 自定义滚动条样式 */
/* Custom scrollbar styles */
::-webkit-scrollbar {
width: 8px;
height: 8px;
}
::-webkit-scrollbar-track {
@apply bg-gray-100 dark:bg-gray-800;
}
::-webkit-scrollbar-thumb {
@apply rounded-full bg-gray-400 dark:bg-gray-600;
}
::-webkit-scrollbar-thumb:hover {
@apply bg-gray-500 dark:bg-gray-500;
}
/* 自定义选中文字样式 */
/* Custom text selection styles */
::selection {
@apply bg-primary/20 text-primary;
}
/* 自定义动画 */
/* Custom animations */
@keyframes custom-animation {
0%,
100% {
transform: translateY(0);
}
50% {
transform: translateY(-10px);
}
}
.animate-custom {
animation: custom-animation 2s ease-in-out infinite;
}
/* 呼吸灯效果 */
/* Breathing light effect */
@keyframes breathe {
0%,
100% {
opacity: 1;
}
50% {
opacity: 0.5;
}
}
.animate-breathe {
animation: breathe 3s ease-in-out infinite;
}
Tailwind 配置扩展 | Tailwind Configuration Extension
在 tailwind.config.js 中可以扩展主题配置: You can extend theme configuration in tailwind.config.js:
module.exports = {
darkMode: 'class', // 基于类的暗黑模式
// Class-based dark mode
content: ['./app/**/*.{ts,tsx}', './components/**/*.{ts,tsx}', './layouts/**/*.{ts,tsx}'],
theme: {
extend: {
colors: {
// 添加自定义颜色系列
// Add custom color series
brand: {
50: '#eff6ff',
100: '#dbeafe',
200: '#bfdbfe',
300: '#93c5fd',
400: '#60a5fa',
500: '#3b82f6',
600: '#2563eb',
700: '#1d4ed8',
800: '#1e40af',
900: '#1e3a8a',
},
},
fontFamily: {
// 添加自定义字体
// Add custom fonts
custom: ['CustomFont', 'sans-serif'],
display: ['DisplayFont', 'sans-serif'],
},
animation: {
// 添加自定义动画
// Add custom animations
'fade-in': 'fadeIn 0.5s ease-in-out',
'slide-up': 'slideUp 0.5s ease-out',
'bounce-slow': 'bounce 3s infinite',
},
keyframes: {
fadeIn: {
'0%': { opacity: '0' },
'100%': { opacity: '1' },
},
slideUp: {
'0%': { transform: 'translateY(20px)', opacity: '0' },
'100%': { transform: 'translateY(0)', opacity: '1' },
},
},
spacing: {
// 添加自定义间距
// Add custom spacing
128: '32rem',
144: '36rem',
},
borderRadius: {
// 添加自定义圆角
// Add custom border radius
'4xl': '2rem',
},
boxShadow: {
// 添加自定义阴影
// Add custom shadows
glow: '0 0 20px rgba(59, 130, 246, 0.5)',
},
},
},
plugins: [require('@tailwindcss/forms'), require('@tailwindcss/typography')],
}
CSS 变量系统 | CSS Variable System
使用 CSS 变量实现主题动态切换: Use CSS variables for dynamic theme switching:
/* css/tailwind.css */
:root {
/* 颜色变量 */
/* Color variables */
--color-primary: 59 130 246; /* RGB values */
--color-secondary: 139 92 246;
/* 间距变量 */
/* Spacing variables */
--spacing-unit: 0.25rem;
/* 字体大小 */
/* Font sizes */
--font-size-base: 1rem;
/* 过渡时间 */
/* Transition durations */
--transition-fast: 150ms;
--transition-normal: 300ms;
}
.dark {
--color-primary: 96 165 250;
--color-secondary: 167 139 250;
}
在 Tailwind 中使用: Use in Tailwind:
<div className="bg-[rgb(var(--color-primary))] p-[calc(var(--spacing-unit)*4)]">动态样式内容</div>
// <div>Dynamic style content</div>
组件级样式修改 | Component-level Style Modification
对于特定组件,可以直接修改组件文件。例如修改导航栏样式: For specific components, you can modify the component file directly. For example, modifying navigation bar styles:
// components/Header.tsx
import { useState, useEffect } from 'react'
const nav = `
sticky top-0 z-50
bg-white/80 dark:bg-gray-900/80
backdrop-blur-md
border-b border-gray-200 dark:border-gray-700
transition-all duration-300
`
const navLinkClass = `
relative
px-4 py-2
text-gray-700 dark:text-gray-300
hover:text-primary dark:hover:text-primary
transition-colors duration-200
after:content-[''] after:absolute after:bottom-0 after:left-0 after:w-0 after:h-0.5
after:bg-primary after:transition-all after:duration-300
hover:after:w-full
`
export default function Header() {
const [scrolled, setScrolled] = useState(false)
useEffect(() => {
const handleScroll = () => {
setScrolled(window.scrollY > 20)
}
window.addEventListener('scroll', handleScroll)
return () => window.removeEventListener('scroll', handleScroll)
}, [])
return (
<header className={`${nav} ${scrolled ? 'shadow-lg' : ''}`}>
<nav className="container mx-auto px-4">{/* 导航内容 */}</nav>
{/* Navigation content */}
</header>
)
}
动态样式和条件样式 | Dynamic and Conditional Styles
使用 clsx 或 classnames 实现动态样式: Use clsx or classnames for dynamic styles:
import { clsx } from 'clsx'
import { twMerge } from 'tailwind-merge'
// 合并 Tailwind 类的工具函数
// Utility function to merge Tailwind classes
function cn(...inputs) {
return twMerge(clsx(inputs))
}
export function Button({ variant = 'primary', size = 'md', children, className }) {
const baseStyles = 'rounded-lg font-medium transition-all duration-200'
const variants = {
primary: 'bg-primary text-white hover:bg-primary-dark',
secondary: 'bg-gray-200 text-gray-800 hover:bg-gray-300',
outline: 'border-2 border-primary text-primary hover:bg-primary hover:text-white',
}
const sizes = {
sm: 'px-3 py-1.5 text-sm',
md: 'px-4 py-2 text-base',
lg: 'px-6 py-3 text-lg',
}
return (
<button className={cn(baseStyles, variants[variant], sizes[size], className)}>
{children}
</button>
)
}
三、如何修改背景色 | III. How to Modify Background Color
修改全局背景 | Modify Global Background
在 app/layout.tsx 中修改 body 的背景: Modify body background in app/layout.tsx:
// app/layout.tsx
export default function RootLayout({ children }) {
return (
<html lang="zh-cn" className="scroll-smooth">
<body className="bg-gray-50 dark:bg-gray-900">{/* 页面内容 */}</body>
{/* Page content */}
</html>
)
}
渐变背景 | Gradient Background
项目当前使用了渐变背景效果: The project currently uses gradient background effect:
// app/layout.tsx
<body className="
animate-gradient
bg-gradient-to-r
from-indigo-50 via-purple-50 to-pink-50
dark:from-stone-900 dark:via-zinc-900 dark:to-slate-900
pl-[calc(100vw-100%)]
text-black antialiased dark:text-white
">
关键类说明: Key class descriptions:
animate-gradient: 自定义动画类,让渐变缓慢移动Custom animation class for slow gradient movement
bg-gradient-to-r: 水平渐变方向Horizontal gradient direction
from-{color},via-{color},to-{color}: 渐变颜色点Gradient color points
dark:前缀: 暗黑模式下的样式Dark mode styles
pl-[calc(100vw-100%)]: 防止滚动条出现时的布局偏移Prevent layout shift when scrollbar appears
antialiased: 字体抗锯齿Font antialiasing
修改渐变动画 | Modify Gradient Animation
在 css/tailwind.css 中定义动画: Define animation in css/tailwind.css:
@keyframes gradient {
0% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;
}
}
.animate-gradient {
background-size: 200% 200%;
animation: gradient 10s ease infinite;
}
/* 更快的渐变动画 */
/* Faster gradient animation */
.animate-gradient-fast {
background-size: 200% 200%;
animation: gradient 5s ease infinite;
}
/* 垂直渐变动画 */
/* Vertical gradient animation */
@keyframes gradient-vertical {
0% {
background-position: 50% 0%;
}
50% {
background-position: 50% 100%;
}
100% {
background-position: 50% 0%;
}
}
.animate-gradient-vertical {
background-size: 200% 200%;
animation: gradient-vertical 15s ease infinite;
}
四、如何添加组件 | IV. How to Add Components
创建新组件 | Create New Component
在 components/ 目录下创建新的组件文件: Create new component file in components/ directory:
// components/MyComponent.tsx
import { ReactNode } from 'react'
interface MyComponentProps {
title: string
children?: ReactNode
variant?: 'default' | 'primary' | 'secondary'
}
export default function MyComponent({ title, children, variant = 'default' }: MyComponentProps) {
const variants = {
default: 'border-gray-200 bg-white dark:border-gray-700 dark:bg-gray-800',
primary: 'border-primary bg-primary/5 dark:bg-primary/10',
secondary: 'border-purple-300 bg-purple-50 dark:border-purple-700 dark:bg-purple-900/20',
}
return (
<div
className={`
rounded-lg border p-4 shadow-sm transition-all duration-200
hover:shadow-md
${variants[variant]}
`}
>
<h3 className="mb-2 text-lg font-semibold">{title}</h3>
{children}
</div>
)
}
在 MDX 中使用组件 | Use Components in MDX
首先在 components/MDXComponents.tsx 中注册组件: First register component in components/MDXComponents.tsx:
// components/MDXComponents.tsx
import { MDXComponents } from 'mdx/types'
import Image from './Image'
import TOCInline from './TOCInline'
import MyComponent from './MyComponent'
import CustomLink from './Link'
export const components: MDXComponents = {
Image,
TOCInline,
MyComponent,
a: CustomLink,
}
然后在 MDX 文件中直接使用: Then use directly in MDX files:
---
title: 使用自定义组件
date: 2026-01-02
tags: ['nextjs', 'mdx']
---
## 引言
这是一个演示如何使用自定义组件的文章。
This is an article demonstrating how to use custom components.
<MyComponent title="提示信息" variant="primary">
这是组件的内容部分。你可以在这里放置任何内容。 This is the content part of the component. You can
place any content here.
</MyComponent>
五、如何添加进度条 | V. How to Add Progress Bar
项目包含一个精美的阅读进度条组件,位于 components/ProgressBar.tsx。 The project includes a beautiful reading progress bar component at components/ProgressBar.tsx.
使用进度条 | Use Progress Bar
在 app/layout.tsx 中引入: Import in app/layout.tsx:
import ProgressBar from '@/components/ProgressBar'
export default function RootLayout({ children }) {
return (
<html>
<body>
<ProgressBar />
{children}
</body>
</html>
)
}
六、如何添加文章 TOC 组件 | VI. How to Add Article TOC Component
文章目录(Table of Contents)组件位于 components/TOCInline.tsx。 The Table of Contents component is located at components/TOCInline.tsx.
在文章中使用 TOC | Use TOC in Articles
在 MDX 文件中直接使用: Use directly in MDX files:
---
title: 你的文章标题
date: 2026-01-02
tags: ['nextjs']
---
# Your Article Title
## 引言
文章引言内容,介绍文章的主要内容...
Article introduction content, describing the main content...
<TOCInline />
## 第一节:基础概念
这是第一节的详细内容...
This is the detailed content of section 1...
## 第二节:进阶应用
这是第二节的详细内容...
This is the detailed content of section 2...
七、其他实用组件 | VII. Other Useful Components
加载进度条 (LoadingBar) | Loading Progress Bar
位于 components/LoadingBar.tsx,在路由切换时显示加载进度。 Located at components/LoadingBar.tsx, displays loading progress during route transitions.
特性: Features:
监听页面加载和路由切换
Monitors page loading and route transitions
自动完成机制(最多5秒)
Auto-completion mechanism (max 5 seconds)
渐变色动画效果
Gradient color animation effect
防止重复触发
Prevents duplicate triggers
主题切换 (ThemeSwitch) | Theme Switcher
位于 components/ThemeSwitch.tsx,支持亮色/暗色主题切换。 Located at components/ThemeSwitch.tsx, supports light/dark theme switching.
特性: Features:
使用 next-themes 管理主题
Uses next-themes for theme management
优雅的切换动画
Elegant switching animation
太阳/月亮图标
Sun/moon icons
自动适配系统主题
Auto-adapts to system theme
返回顶部 (ScrollTopAndComment) | Back to Top
位于 components/ScrollTopAndComment.tsx,提供返回顶部和跳转评论区的按钮。 Located at components/ScrollTopAndComment.tsx, provides back-to-top and jump-to-comment buttons.
特性: Features:
滚动超过50px后显示
Shows after scrolling more than 50px
返回顶部功能
Back to top functionality
跳转到评论区
Jump to comment section
平滑滚动动画
Smooth scroll animation
八、性能优化技巧 | VIII. Performance Optimization Tips
React 性能优化 | React Performance Optimization
使用 React.memo 防止不必要的重渲染 | Use React.memo to prevent unnecessary re-renders
import { memo } from 'react'
const ExpensiveComponent = memo(function ExpensiveComponent({ data }: { data: any }) {
// 组件逻辑
// Component logic
return <div>{/* 渲染内容 */}</div>
// Render content
})
使用 useMemo 缓存计算结果 | Use useMemo to cache calculation results
import { useMemo } from 'react'
function ProcessedList({ items }: { items: any[] }) {
const processed = useMemo(() => {
return items.map((item) => {
// 昂贵的计算
// Expensive calculation
return transform(item)
})
}, [items])
return <div>{processed}</div>
}
使用 useCallback 稳定函数引用 | Use useCallback to stabilize function references
import { useCallback } from 'react'
function ParentComponent() {
const handleClick = useCallback(() => {
// 处理点击
// Handle click
}, [])
return <ChildComponent onClick={handleClick} />
}
代码分割和懒加载 | Code Splitting and Lazy Loading
import dynamic from 'next/dynamic'
const HeavyComponent = dynamic(() => import('@/components/HeavyComponent'), {
loading: () => <div>Loading...</div>,
ssr: false, // 客户端渲染
// Client-side rendering
})
九、SEO 优化 | IX. SEO Optimization
元数据配置 | Metadata Configuration
// app/layout.tsx
export const metadata = {
title: {
default: '网站标题', // Website title
template: '%s | 网站标题', // %s | Website title
},
description: '网站描述', // Website description
keywords: ['关键词1', '关键词2'], // Keywords
openGraph: {
title: '网站标题', // Website title
description: '网站描述', // Website description
url: 'https://example.com',
images: [
{
url: 'https://example.com/og.jpg',
width: 1200,
height: 630,
},
],
},
}
总结 | Summary
这个 Next.js 博客模板提供了完善的组件体系和样式系统,通过合理使用和扩展这些功能,可以快速构建出功能完善、外观精美的个人博客。 This Next.js blog template provides a comprehensive component system and style system. Through proper use and extension of these features, you can quickly build a fully functional, beautiful personal blog.
学习路径建议 | Learning Path Recommendations
基础阶段:熟悉项目结构,理解组件系统
Basic Stage: Familiarize with project structure, understand component system
进阶阶段:定制样式,添加自定义组件
Advanced Stage: Customize styles, add custom components
优化阶段:性能优化,SEO 提升
Optimization Stage: Performance optimization, SEO improvement
高级阶段:扩展功能,集成第三方服务
Expert Stage: Extend features, integrate third-party services