Skip to content

Next.js Version โ€‹

HaloLight Next.js version is built on Next.js 14 App Router with React 18 + TypeScript.

Live Preview: https://halolight.h7ml.cn/

GitHub: https://github.com/halolight/halolight

Features โ€‹

  • ๐Ÿ—๏ธ Next.js 14 App Router - Server components & streaming rendering
  • โšก Zustand State Management - Lightweight state management solution
  • ๐ŸŽจ Theme System - 11 skins, dark/light mode, View Transitions
  • ๐Ÿ” Authentication System - Complete login/register/password recovery flow
  • ๐Ÿ“Š Dashboard - Data visualization & business management
  • ๐Ÿ›ก๏ธ Permission Control - RBAC fine-grained permission management
  • ๐Ÿ“‘ Multi-Tab Navigation - Tab bar management
  • โŒ˜ Command Palette - Keyboard shortcut navigation

Tech Stack โ€‹

TechnologyVersionDescription
Next.js14.xReact full-stack framework (App Router)
React18.xUI library
TypeScript5.xType safety
Tailwind CSS4.xAtomic CSS
shadcn/uilatestUI component library (28 components)
Zustand5.xState management (6 Stores)
TanStack Query5.xServer state
React Hook Form7.xForm handling
Zod4.xData validation
react-grid-layout1.xDrag-and-drop layout
Recharts3.xChart visualization
Framer Motion12.xAnimation effects
Mock.js1.xData mocking
next-pwa5.xPWA support

Core Features โ€‹

  • Configurable Dashboard - 9 widget types, drag-and-drop layout, responsive adaptation
  • Multi-Tab Navigation - Browser-style tabs, context menu, state caching
  • Permission System - RBAC permission control, route guards, permission components
  • Theme System - 11 skins, dark/light mode, View Transitions
  • Multi-Account Switching - Quick account switch, remember login state
  • Command Palette - Keyboard shortcuts (โŒ˜K), global search
  • Real-time Notifications - WebSocket push, notification center

Directory Structure โ€‹

halolight/
โ”œโ”€โ”€ src/
โ”‚   โ”œโ”€โ”€ app/                      # App Router pages
โ”‚   โ”‚   โ”œโ”€โ”€ (auth)/              # Auth route group
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ login/           # Login
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ register/        # Register
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ forgot-password/ # Forgot password
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ reset-password/  # Reset password
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ layout.tsx       # Auth layout
โ”‚   โ”‚   โ”œโ”€โ”€ (dashboard)/         # Dashboard route group
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ page.tsx         # Dashboard home (configurable)
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ accounts/        # Account & permissions
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ analytics/       # Analytics
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ calendar/        # Calendar
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ docs/            # Help docs
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ documents/       # Document management
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ files/           # File storage
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ messages/        # Message center
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ notifications/   # Notification center
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ profile/         # User profile
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ users/           # User management
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ settings/        # System settings
โ”‚   โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ teams/       # Team management
โ”‚   โ”‚   โ”‚   โ”‚       โ””โ”€โ”€ roles/   # Role management
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ layout.tsx       # Dashboard layout
โ”‚   โ”‚   โ”œโ”€โ”€ (legal)/             # Legal route group
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ privacy/         # Privacy policy
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ terms/           # Terms of service
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ layout.tsx
โ”‚   โ”‚   โ”œโ”€โ”€ layout.tsx           # Root layout
โ”‚   โ”‚   โ”œโ”€โ”€ error.tsx            # Error page
โ”‚   โ”‚   โ””โ”€โ”€ not-found.tsx        # 404 page
โ”‚   โ”œโ”€โ”€ components/
โ”‚   โ”‚   โ”œโ”€โ”€ ui/                  # shadcn/ui components (28)
โ”‚   โ”‚   โ”œโ”€โ”€ layout/              # Layout components (11)
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ admin-layout.tsx # Admin layout
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ sidebar.tsx      # Collapsible sidebar
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ header.tsx       # Header (notifications/errors/user menu)
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ footer.tsx       # Footer
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ tab-bar.tsx      # Multi-tab navigation
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ command-menu.tsx # Command palette (โŒ˜K)
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ quick-settings.tsx # UI settings panel
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ theme-toggle.tsx # Theme toggle
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ pending-overlay.tsx # Loading overlay
โ”‚   โ”‚   โ”œโ”€โ”€ dashboard/           # Dashboard components
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ configurable-dashboard.tsx # Configurable dashboard
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ charts.tsx       # Chart components
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ stats-card.tsx   # Stats card
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ recent-activity.tsx # Recent activity
โ”‚   โ”‚   โ””โ”€โ”€ shared/              # Shared components
โ”‚   โ”œโ”€โ”€ hooks/                   # React Hooks (15)
โ”‚   โ”‚   โ”œโ”€โ”€ use-users.ts         # User CRUD
โ”‚   โ”‚   โ”œโ”€โ”€ use-teams.ts         # Team management
โ”‚   โ”‚   โ”œโ”€โ”€ use-messages.ts      # Message management
โ”‚   โ”‚   โ”œโ”€โ”€ use-notifications.ts # Notification management
โ”‚   โ”‚   โ”œโ”€โ”€ use-calendar.ts      # Calendar data
โ”‚   โ”‚   โ”œโ”€โ”€ use-documents.ts     # Document management
โ”‚   โ”‚   โ”œโ”€โ”€ use-files.ts         # File management
โ”‚   โ”‚   โ”œโ”€โ”€ use-dashboard.ts     # Dashboard state
โ”‚   โ”‚   โ”œโ”€โ”€ use-dashboard-data.ts # Dashboard data Hook collection
โ”‚   โ”‚   โ”œโ”€โ”€ use-chart-palette.ts # Chart palette (theme-aware)
โ”‚   โ”‚   โ”œโ”€โ”€ use-action-mutation.ts # Server Action wrapper
โ”‚   โ”‚   โ”œโ”€โ”€ use-keep-alive.tsx   # Page state caching
โ”‚   โ”‚   โ”œโ”€โ”€ use-tdk.ts           # TDK management
โ”‚   โ”‚   โ””โ”€โ”€ use-title.ts         # Page title
โ”‚   โ”œโ”€โ”€ stores/                  # Zustand Stores (6)
โ”‚   โ”‚   โ”œโ”€โ”€ auth-store.ts        # Auth state (with multi-account)
โ”‚   โ”‚   โ”œโ”€โ”€ ui-settings-store.ts # UI settings
โ”‚   โ”‚   โ”œโ”€โ”€ dashboard-store.ts   # Dashboard state
โ”‚   โ”‚   โ”œโ”€โ”€ navigation-store.ts  # Navigation state
โ”‚   โ”‚   โ”œโ”€โ”€ tabs-store.ts        # Tab state
โ”‚   โ”‚   โ””โ”€โ”€ error-store.ts       # Error collection
โ”‚   โ”œโ”€โ”€ providers/               # React Providers (8)
โ”‚   โ”‚   โ”œโ”€โ”€ app-providers.tsx    # Provider aggregation
โ”‚   โ”‚   โ”œโ”€โ”€ auth-provider.tsx    # Auth Provider
โ”‚   โ”‚   โ”œโ”€โ”€ theme-provider.tsx   # Theme Provider
โ”‚   โ”‚   โ”œโ”€โ”€ query-provider.tsx   # TanStack Query
โ”‚   โ”‚   โ”œโ”€โ”€ error-provider.tsx   # Error handling
โ”‚   โ”‚   โ”œโ”€โ”€ permission-provider.tsx # Permission check
โ”‚   โ”‚   โ”œโ”€โ”€ websocket-provider.tsx # WebSocket real-time notifications
โ”‚   โ”‚   โ””โ”€โ”€ keep-alive-provider.tsx # Page keep-alive
โ”‚   โ”œโ”€โ”€ actions/                 # Server Actions
โ”‚   โ”œโ”€โ”€ config/                  # Configuration
โ”‚   โ”‚   โ”œโ”€โ”€ routes.ts            # Routes & permissions config
โ”‚   โ”‚   โ””โ”€โ”€ tdk.ts               # TDK config
โ”‚   โ”œโ”€โ”€ lib/                     # Utility library
โ”‚   โ”‚   โ””โ”€โ”€ api/                 # API client
โ”‚   โ”œโ”€โ”€ mock/                    # Mock data (9 modules)
โ”‚   โ””โ”€โ”€ middleware.ts            # Middleware (auth + security headers)
โ”œโ”€โ”€ public/
โ”‚   โ”œโ”€โ”€ manifest.json            # PWA manifest
โ”‚   โ”œโ”€โ”€ sw.js                    # Service Worker
โ”‚   โ”œโ”€โ”€ icons/                   # PWA icons (8 sizes)
โ”‚   โ”œโ”€โ”€ screenshots/             # PWA screenshots
โ”‚   โ””โ”€โ”€ fonts/                   # Self-hosted fonts
โ”œโ”€โ”€ next.config.mjs              # Next.js + PWA config
โ”œโ”€โ”€ tailwind.config.js
โ”œโ”€โ”€ tsconfig.json
โ””โ”€โ”€ package.json

Quick Start โ€‹

Environment Requirements โ€‹

  • Node.js >= 18.0.0
  • pnpm >= 9.x

Installation โ€‹

bash
git clone https://github.com/halolight/halolight.git
cd halolight
pnpm install

Environment Variables โ€‹

bash
cp .env.example .env.local
env
# .env.local example
NEXT_PUBLIC_API_URL=/api
NEXT_PUBLIC_MOCK=true              # Enable Mock data
NEXT_PUBLIC_DEMO_EMAIL=admin@halolight.h7ml.cn
NEXT_PUBLIC_DEMO_PASSWORD=123456
NEXT_PUBLIC_SHOW_DEMO_HINT=false
NEXT_PUBLIC_WS_URL=                # WebSocket URL
NEXT_PUBLIC_APP_TITLE=Admin Pro
NEXT_PUBLIC_BRAND_NAME=Halolight

Start Development โ€‹

bash
pnpm dev

Visit http://localhost:3000

Build for Production โ€‹

bash
pnpm build
pnpm start

Demo Account โ€‹

RoleEmailPassword
Adminadmin@halolight.h7ml.cn123456
Useruser@halolight.h7ml.cn123456

Core Functionality โ€‹

1. State Management (Zustand) โ€‹

tsx
// stores/auth-store.ts
interface AuthState {
  user: AccountWithToken | null
  accounts: AccountWithToken[]        // Multi-account list
  activeAccountId: string | null      // Current account

  login: (data: LoginRequest) => Promise<void>
  register: (data: RegisterRequest) => Promise<void>
  logout: () => Promise<void>
  switchAccount: (accountId: string) => Promise<void>  // Quick account switch
  forgotPassword: (email: string) => Promise<void>
  resetPassword: (token: string, password: string) => Promise<void>
  checkAuth: () => Promise<void>
}

// Cookie-based token storage with "Remember me" support (7 days / 1 day)
Cookies.set("token", response.token, {
  expires: data.remember ? 7 : 1,
  secure: process.env.NODE_ENV === "production",
  sameSite: "strict",
})

2. Data Fetching (TanStack Query) โ€‹

tsx
// hooks/use-users.ts
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'

export function useUsers() {
  const queryClient = useQueryClient()

  // Query user list
  const { data, isLoading } = useQuery({
    queryKey: ['users'],
    queryFn: fetchUsers,
  })

  // Create user
  const createUser = useMutation({
    mutationFn: createUserApi,
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['users'] })
    },
  })

  return { data, isLoading, createUser }
}

3. Permission Control โ€‹

tsx
// Route permission config
export const ROUTE_PERMISSIONS: Record<string, Permission> = {
  "/": "dashboard:view",
  "/users": "users:view",
  "/analytics": "analytics:view",
  // ...
}

// Permission check
const { hasPermission } = usePermission()
if (hasPermission("users:delete")) {
  // Show delete button
}
tsx
// Permission guard component
<PermissionGuard permission="users:delete" fallback={<Disabled />}>
  <DeleteButton />
</PermissionGuard>

4. Draggable Dashboard โ€‹

tsx
// Dashboard edit mode
const { isEditing, setIsEditing, addWidget, removeWidget, resetToDefault } = useDashboardStore()

// Responsive layout (columns auto-adapt)
// lg: 12 cols, md: 8 cols, sm: 4 cols, xs: 2 cols, mobile: 1 col

Supports 9 widget types:

Widget TypeDescriptionData Source
statsStatistics card (4 metrics)useDashboardStats
chart-lineLine chart (visit trends)useDashboardVisits
chart-barBar chart (sales statistics)useDashboardSales
chart-piePie chart (traffic distribution)useDashboardPie
recent-usersRecent users listuseDashboardUsers
notificationsNotifications listuseDashboardNotifications
tasksTodo tasksuseDashboardTasks
calendarToday's scheduleuseDashboardCalendar
quick-actionsQuick action shortcutsStatic config

Theme System โ€‹

Skin Presets โ€‹

Supports 11 skin presets with live preview and smooth transition animations:

PresetNameDescription
defaultShadcn ยท NeutralOfficial default neutral colors
blueShadcn ยท BlueBlue primary + cool-toned charts
emeraldShadcn ยท EmeraldFresh green, ideal for data display
amberShadcn ยท AmberAmber/orange, warm and vibrant
violetShadcn ยท VioletHigh-saturation purple, tech feel
roseShadcn ยท RoseRose primary, contrasting charts
tealShadcn ยท TealTeal primary, modern feel
slateShadcn ยท SlateLow-saturation gray-blue, utilitarian
oceanLegacy ยท Ocean BlueBlue-green gradient
sunsetLegacy ยท Sunset OrangeOrange-pink contrast
auroraLegacy ยท Aurora GreenCyan-green + purple

CSS Variables (OKLch) โ€‹

css
/* Example variable definitions */
:root {
  --background: 100% 0 0;
  --foreground: 14.9% 0.017 285.75;
  --primary: 51.1% 0.262 276.97;
  --primary-foreground: 100% 0 0;
  --muted: 96.4% 0.004 285.75;
  --accent: 96.4% 0.004 285.75;
  /* ... */
}

Page Routes โ€‹

PathPagePermission
/Redirect to dashboard-
/loginLoginPublic
/registerRegisterPublic
/forgot-passwordForgot passwordPublic
/reset-passwordReset passwordPublic
/dashboardConfigurable dashboarddashboard:view
/accountsAccount & permissionssettings:view
/analyticsAnalyticsanalytics:view
/calendarCalendarcalendar:view
/documentsDocument managementdocuments:view
/filesFile storagefiles:view
/messagesMessage centermessages:view
/notificationsNotification centernotifications:view
/usersUser managementusers:view
/settingsSystem settingssettings:view
/settings/teamsTeam settingssettings:view
/settings/teams/rolesRole managementsettings:view
/profileUser profilesettings:view
/docsHelp docsdocuments:view
/privacyPrivacy policyPublic
/termsTerms of servicePublic

Environment Variables โ€‹

Configuration Example โ€‹

bash
cp .env.example .env.local
env
# .env.local
NEXT_PUBLIC_API_URL=/api
NEXT_PUBLIC_MOCK=true
NEXT_PUBLIC_DEMO_EMAIL=admin@halolight.h7ml.cn
NEXT_PUBLIC_DEMO_PASSWORD=123456
NEXT_PUBLIC_SHOW_DEMO_HINT=false
NEXT_PUBLIC_WS_URL=
NEXT_PUBLIC_APP_TITLE=Admin Pro
NEXT_PUBLIC_BRAND_NAME=Halolight

Variable Description โ€‹

VariableDescriptionDefault
NEXT_PUBLIC_API_URLAPI base path/api
NEXT_PUBLIC_MOCKEnable Mock datatrue
NEXT_PUBLIC_DEMO_EMAILDemo account emailadmin@halolight.h7ml.cn
NEXT_PUBLIC_DEMO_PASSWORDDemo account password123456
NEXT_PUBLIC_SHOW_DEMO_HINTShow demo hintfalse
NEXT_PUBLIC_WS_URLWebSocket URL-
NEXT_PUBLIC_APP_TITLEApplication titleAdmin Pro
NEXT_PUBLIC_BRAND_NAMEBrand nameHalolight

Usage โ€‹

tsx
// Use in client components
const apiUrl = process.env.NEXT_PUBLIC_API_URL
const isMock = process.env.NEXT_PUBLIC_MOCK === 'true'

Common Commands โ€‹

bash
pnpm dev            # Start development server
pnpm build          # Production build
pnpm start          # Preview production build
pnpm lint           # Code linting
pnpm lint:fix       # Auto fix
pnpm type-check     # Type checking
pnpm test           # Run tests
pnpm test:coverage  # Test coverage

Testing โ€‹

bash
pnpm test           # Run tests (watch mode)
pnpm test:run       # Single run
pnpm test:coverage  # Coverage report
pnpm test:ui        # Vitest UI interface

Test Example โ€‹

tsx
// __tests__/components/button.test.tsx
import { render, screen, fireEvent } from '@testing-library/react'
import { Button } from '@/components/ui/button'

describe('Button Component', () => {
  it('renders correctly', () => {
    render(<Button>Click me</Button>)
    expect(screen.getByText('Click me')).toBeInTheDocument()
  })

  it('handles click events', () => {
    const handleClick = vi.fn()
    render(<Button onClick={handleClick}>Click me</Button>)
    fireEvent.click(screen.getByText('Click me'))
    expect(handleClick).toHaveBeenCalledTimes(1)
  })
})

Configuration โ€‹

Next.js Configuration โ€‹

js
// next.config.mjs
import withPWA from "next-pwa"

const nextConfig = {
  // Package import optimization - reduce bundle size
  experimental: {
    optimizePackageImports: [
      "@radix-ui/react-*",
      "lucide-react",
      "framer-motion",
      "@tanstack/react-query",
      "recharts",
      "zustand",
    ],
  },

  // Remove console in production
  compiler: {
    removeConsole: { exclude: ["error", "warn"] },
  },

  // Disable source maps
  productionBrowserSourceMaps: false,

  // Image optimization
  images: {
    formats: ["image/avif", "image/webp"],
  },
}

const pwaConfig = withPWA({
  dest: "public",
  register: true,
  skipWaiting: true,
  disable: process.env.NODE_ENV === "development",
})

export default pwaConfig(nextConfig)

Deployment โ€‹

Deploy with Vercel

bash
vercel

Docker โ€‹

dockerfile
FROM node:18-alpine
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN npm install -g pnpm && pnpm install --frozen-lockfile
COPY . .
RUN pnpm build
EXPOSE 3000
CMD ["pnpm", "start"]
bash
docker build -t halolight-nextjs .
docker run -p 3000:3000 halolight-nextjs

Other Platforms โ€‹

CI/CD โ€‹

The project has a complete GitHub Actions CI workflow configured:

yaml
# .github/workflows/ci.yml
name: CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: pnpm/action-setup@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: pnpm
      - run: pnpm install --frozen-lockfile
      - run: pnpm lint
      - run: pnpm type-check

  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: pnpm/action-setup@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: pnpm
      - run: pnpm install --frozen-lockfile
      - run: pnpm test:coverage
      - uses: codecov/codecov-action@v4
        with:
          token: ${{ secrets.CODECOV_TOKEN }}

  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: pnpm/action-setup@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: pnpm
      - run: pnpm install --frozen-lockfile
      - run: pnpm build

  security:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: pnpm/action-setup@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: pnpm
      - run: pnpm audit --audit-level=high

Advanced Features โ€‹

Multi-Tab Navigation โ€‹

tsx
// stores/tabs-store.ts
interface Tab {
  id: string
  title: string
  path: string
  icon?: string
  closable?: boolean  // Home tab not closable
}

// Context menu features
- Refresh page
- Close tab
- Close others
- Close right tabs
- Close all

Page State Caching (Keep-Alive) โ€‹

tsx
// hooks/use-keep-alive.tsx

// Auto save/restore scroll position
useScrollRestore()

// Save form state
const [values, saveValues, clearCache] = useFormCache('filter-form', initialValues)

// Save custom state
const [state, setState] = useStateCache('my-key', initialValue)

Command Palette (โŒ˜K) โ€‹

tsx
// components/layout/command-menu.tsx
// Supports keyboard quick navigation, theme switching, account switching, logout, etc.

Shortcuts:
- โŒ˜K / Ctrl+K - Open command palette
- Search pages - Quick navigation to any page
- Switch theme - Toggle dark/light mode
- Switch account - Quick account switching

Real-time Notifications (WebSocket) โ€‹

tsx
// providers/websocket-provider.tsx
const { status, lastMessage, sendMessage, reconnect } = useWebSocket()

// Listen for new notifications
useRealtimeNotifications((notification) => {
  console.log('New notification:', notification)
})

// Connection status
status === 'Open' // Connected
status === 'Connecting' // Connecting
status === 'Closed' // Disconnected

PWA Support โ€‹

js
// next.config.mjs
const pwaConfig = withPWA({
  dest: "public",
  register: true,
  skipWaiting: true,
  disable: process.env.NODE_ENV === "development",
  runtimeCaching: [
    // Font caching (1 year)
    { urlPattern: /\.(?:woff|woff2|ttf)$/i, handler: "CacheFirst" },
    // Image caching (24 hours)
    { urlPattern: /\.(?:jpg|png|svg|webp)$/i, handler: "StaleWhileRevalidate" },
    // Next.js static assets (1 year)
    { urlPattern: /\/_next\/static\/.+\.(js|css)$/i, handler: "CacheFirst" },
    // Page data (1 hour)
    { urlPattern: /\/_next\/data\/.+\.json$/i, handler: "NetworkFirst" },
  ],
})

Features:

  • Offline Access - Service Worker caches static assets
  • Install to Desktop - Supports Add to Home Screen
  • Self-hosted Fonts - Inter + JetBrains Mono
  • Icon Support - 8 sizes (72x72 ~ 512x512)

Performance Optimization โ€‹

Image Optimization โ€‹

tsx
// Use Next.js Image component
import Image from 'next/image'

<Image
  src="/images/hero.png"
  alt="Hero"
  width={800}
  height={600}
  priority // Priority loading
  placeholder="blur" // Blur placeholder
/>

// next.config.mjs
images: {
  formats: ["image/avif", "image/webp"],
}

Lazy Loading Components โ€‹

tsx
// Dynamic import components
import dynamic from 'next/dynamic'

const DashboardChart = dynamic(
  () => import('@/components/dashboard/chart'),
  {
    loading: () => <Skeleton />,
    ssr: false // Disable SSR
  }
)

Preloading โ€‹

tsx
// Route preloading
import Link from 'next/link'

<Link href="/dashboard" prefetch>
  Dashboard
</Link>

// Data preloading
queryClient.prefetchQuery({
  queryKey: ['users'],
  queryFn: fetchUsers,
})

Package Import Optimization โ€‹

js
// next.config.mjs
experimental: {
  optimizePackageImports: [
    "@radix-ui/react-*",
    "lucide-react",
    "framer-motion",
    "@tanstack/react-query",
    "recharts",
    "zustand",
  ],
}

FAQ โ€‹

Q: How to disable Mock data? โ€‹

A: Set NEXT_PUBLIC_MOCK=false in .env.local and configure real API address.

env
NEXT_PUBLIC_MOCK=false
NEXT_PUBLIC_API_URL=https://api.example.com

Q: How to add a new page? โ€‹

A: Create a new directory and page.tsx file under src/app/(dashboard).

tsx
// src/app/(dashboard)/my-page/page.tsx
export default function MyPage() {
  return <div>My Page</div>
}

// Add route permission
// src/config/routes.ts
export const ROUTE_PERMISSIONS = {
  // ...
  "/my-page": "my-page:view",
}

Q: How to customize theme colors? โ€‹

A: Modify CSS variables in tailwind.config.js.

js
// tailwind.config.js
module.exports = {
  theme: {
    extend: {
      colors: {
        primary: {
          DEFAULT: 'oklch(var(--primary))',
          foreground: 'oklch(var(--primary-foreground))',
        },
      },
    },
  },
}
css
/* app/globals.css */
:root {
  --primary: 51.1% 0.262 276.97; /* Change to your color */
}

Q: How to disable PWA? โ€‹

A: Set disable: true in next.config.mjs.

js
const pwaConfig = withPWA({
  dest: "public",
  disable: true, // Disable PWA
})

Q: How to deploy to static hosting platforms? โ€‹

A: Configure static export mode.

js
// next.config.mjs
export default {
  output: 'export',
  images: {
    unoptimized: true, // Need to disable image optimization for static export
  },
}
bash
pnpm build
# Output to out/ directory

Comparison with Other Versions โ€‹

FeatureNext.jsVueAngular
SSR/SSGโœ…โœ… (Nuxt)โœ… (Universal)
State ManagementZustandPiniaServices + RxJS
RouterApp RouterVue RouterAngular Router
Build ToolNext.jsViteesbuild + Vite
Component Libraryshadcn/uishadcn-vueAngular Material
Learning CurveMediumLowHigh
PerformanceExcellentExcellentExcellent