Building Your Starter App with Next.js 🛠️
🌟 Follow these steps to create and set up your new Next.js starter app, complete with essential tools for a smooth development experience. 🔧
Steps to Setup
Step 1: Create a Next.js Application
npx create-next-app@latest
This command initializes a new Next.js project in a directory of your choice, setting up the necessary files and dependencies.
Step 2: Install Prettier and ESLint
npm i -D prettier eslint-config-prettier eslint-plugin-prettier
Install Prettier and ESLint along with the necessary configuration for integrating Prettier with ESLint.
Step 3: Install Tailwind CSS ESLint Plugin
npm install eslint-plugin-tailwindcss --save-dev
Ensure your Tailwind CSS classes are linted properly.
Step 4: Install Husky and Lint-Staged
npm i -D husky lint-staged
Husky helps enforce Git hooks, and lint-staged ensures that only staged files are linted and formatted.
Step 5: Initialize Husky
npx husky-init
This command creates a .husky directory with a pre-configured Git hook.
Step 6: Configure Pre-Commit Hook
npx husky add .husky/pre-commit 'npx lint-staged'
Add a pre-commit hook to run lint-staged, which will check your code before committing.
Step 7: Install Commitlint
npm install -D @commitlint/cli @commitlint/config-conventional
To enforce commit message conventions, install Commitlint and its conventional config.
Step 8: Configure Commit Message Hook
npx husky add .husky/commit-msg 'npx --no-install commitlint --edit "$1"'
Add a commit message hook to validate your commit messages using Commitlint.
Step 9: Install Prettier Plugin for Tailwind CSS
npm i -D prettier prettier-plugin-tailwindcss
If you're using Tailwind CSS, install the Prettier plugin for Tailwind CSS.
Step 10: Install Commitizen
npm i -D commitizen
Commitizen helps create standardized commit messages.
Step 11: Install Conventional Changelog Adapter
npm i -D cz-conventional-changelog
Finally, install the Conventional Changelog adapter for Commitizen.
Step 12: Install Next Theme
npm install next-themes
Install Next Theme to enable easy light and dark theme toggling.
Step 13: Install Next PWA
npm install @ducanh2912/next-pwa
Install Next PWA for Progressive Web App support.
Configuration Files
ESLint Configuration (.eslintrc.json)
{
"extends": ["eslint:recommended", "next",
"next/core-web-vitals", "prettier"],
"plugins": ["prettier", "tailwindcss"],
"rules": {
"prettier/prettier": "error",
"tailwindcss/classnames-order": "warn",
"tailwindcss/no-custom-classname": "off"
}
}
Husky Configuration (.husky/pre-commit)
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npx lint-staged
Husky Configuration (.husky/commit-msg)
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npx --no-install commitlint --edit $1
Commitlint Configuration (commitlint.config.js)
module.exports = {
extends: ["@commitlint/config-conventional"],
};
Prettier Configuration (.prettierrc)
{
"plugins": ["prettier-plugin-tailwindcss"],
"semi": true,
"singleQuote": true,
"printWidth": 80,
"tabWidth": 2,
"useTabs": false,
"endOfLine": "lf",
"jsxSingleQuote": false,
"trailingComma": "es5",
"bracketSpacing": true
}
Next-Theme Configuration (theme-provider.tsx, layout.tsx)
// theme-provider.tsx
'use client';
import { ThemeProvider as NextThemesProvider }
from 'next-themes';
import { type ThemeProviderProps }
from 'next-themes/dist/types';
export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
return <NextThemesProvider {...props}>
{children}
</NextThemesProvider>;
}
// layout.tsx
<body>
<ThemeProvider
attribute="class"
defaultTheme="system"
enableSystem
disableTransitionOnChange
>
{children}
</ThemeProvider>
</body>
PWA Configuration (next.config.js)
/** @type {import('next').NextConfig} */
const withPWA = require('@ducanh2912/next-pwa').default({
dest: 'public',
disable: process.env.NODE_ENV === 'development',
register: true,
scope: '/',
cacheOnFrontendNav: true,
aggressiveFrontEndNavCaching: true,
cacheStartUrl: true,
reloadOnOnline: true,
swcMinify: true,
fallbacks: {
document: '/offline',
},
});
const nextConfig = {
reactStrictMode: true,
};
module.exports = withPWA(nextConfig);
Package Configuration (package.json)
{
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start -p 4000",
"preview": "next build && next start -p 4000",
"lint": "eslint src --ext ts,tsx,js,jsx --report-unused-disable-directives --max-warnings 0",
"lint:fix": "eslint src --ext js,jsx,ts,tsx --fix",
"format": "prettier --write 'src/**/*.{js,jsx,ts,tsx,css,html}'",
"commit": "git cz"
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"src/**/*.{ts,tsx,js,jsx}": [
"npm run lint",
"npm run format"
]
},
"config": {
"commitizen": {
"path": "./node_modules/cz-conventional-changelog"
}
},
"dependencies": {
"@ducanh2912/next-pwa": "^10.2.9",
"next": "14.2.15",
"next-themes": "^0.3.0",
"react": "^18",
"react-dom": "^18"
},
"devDependencies": {
"@commitlint/cli": "^19.5.0",
"@commitlint/config-conventional": "^19.5.0",
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
"commitizen": "^4.3.1",
"cz-conventional-changelog": "^3.3.0",
"eslint": "^8",
"eslint-config-next": "14.2.15",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.2.1",
"eslint-plugin-tailwindcss": "^3.17.5",
"husky": "^8.0.3",
"lint-staged": "^15.2.10",
"postcss": "^8",
"prettier": "^3.3.3",
"prettier-plugin-tailwindcss": "^0.6.8",
"tailwindcss": "^3.4.1",
"typescript": "^5"
},
}
Continuous Integration (.github/workflows/ci.yml)
name: Continuous Integration
# Trigger CI on all kinds of branches and PRs
on:
push:
pull_request:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Fetch all history for all branches and tags
- name: Cache node modules
uses: actions/cache@v4
- name: Use Node.js
uses: actions/setup-node@v4
with:
node-version: 'lts/*'
- name: Install dependencies
run: npm install
- name: Run lint
run: npm run lint
- name: Run format check
run: npm run format
- name: Check commit messages
uses: wagoid/commitlint-github-action@v6