This is a stater template for NextJS and Typescript.
- NextJS - A React framework that enables you to build superfast and extremely user-friendly static websites.
- Typescript - A strongly typed programming language that builds on JavaScript.
- Sass - A preprocessor scripting language that is interpreted or compiled into CSS.
- ESlint - A tool for identifying and reporting on patterns found in ECMAScript/JavaScript code.
- Husky - Git hooks that allows custom scripts to be ran against your repository.
- Lint-staged - Helping Husky to run linters against staged git files.
- Commitlint - A tool that lints your commit messages and makes sure they follow a set of rules.
- Stylelint - A linter that avoids errors and enforces conventions in CSS.
- Next SEO - A plugin that makes managing your SEO easier in Next.js projects.
- NodeJS (
v16.17.0
) (mine) - NextJS (
v12.3.0
) - ReactJS (
v18.2.0
)
├── ...
├── src
│ ├── assets # Contains things like (image, icon, logo, .stc)
│ ├── components # Contains reusable UI components like (Header, Footer, Modal, Button, .etc)
│ ├── containers # Contains components which are associated with page component (pages folder)
│ ├── hooks # Contains custom hooks
│ ├── libs # Contains third-party libraries
│ ├── pages # Contains individual page components
│ ├── styles # As global styles
│ ├── types # (only Typescript) Manages types and interfaces
│ └── utils # Contains constants (static data) and utility functions (pure function)
└── ...
1. Clone the repository and install dependencies
$ git clone https://github.com/doduy291/next-js-setup.git <YOUR_FOLDER_NAME>
$ cd <YOUR_FOLDER_NAME>
$ npm install
2. Enable husky (Optional)
$ npm run prepare
⚠️ Ensure that you have got a Git repository, otherwise run this command:git init
. You can pass over this command if you installed packages before.
3. Development
$ npm run dev
You should install ESlint extension in VSCode to dectect errors.
In general the pattern mostly looks like this:
type(scope?): subject #scope is optional; multiple scopes are supported (current delimiter options: "/", "\" and ",")
Real world examples can look like this:
$ git commit -m "build: add new file type"
or
$ git commit -m "fix(server): send cors headers
Type using
- build: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)
- chore: Other changes that do not modify src or test files
- docs: Documentation only changes
- feat: A new feature
- fix: A bug fix
- perf: A code change that improves performance
- refactor: A code change that neither fixes a bug nor adds a feature
- revert: Reverts a previous commit
- style: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
- test: Adding missing tests or correcting existing tests
I recommend installing Stylelint extension in VSCode to show directly underlines for errors rather than typing npx stylelint <path>
to check error
This setup only supports the following files:
CSS
,SCSS
,SASS
.
This is my configs (Prettier and Stylelint requirement)
{
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"stylelint.validate": ["css", "scss"],
"[css]": {
"editor.codeActionsOnSave": {
"source.fixAll.stylelint": true
}
},
"[scss]": {
"editor.codeActionsOnSave": {
"source.fixAll.stylelint": true
}
},
"files.autoSaveDelay": 500
}
Read document to understand better
Variable
Mixin
.any-selector {
width: 100%;
@include media($min: $mobile, $max: $desktop) {
// Some CSS
}
}
or
.any-css2 {
@include media($min: 40em) {
// Some CSS
}
}
const nextConfig = {
reactStrictMode: true,
sassOptions: {
additionalData: `@import "src/styles/_variables.scss"; @import "src/styles/_mixins.scss";`,
},
};
We need to declare these imports in sassOptions to use variable and mixin features in SASS
More rules: @typescript-eslint, @next, React, React Hooks and Import
{
"extends": [
"next/core-web-vitals",
"eslint:recommended",
"plugin:react/recommended",
"plugin:react-hooks/recommended",
"plugin:@typescript-eslint/recommended",
"plugin:@next/next/recommended",
"plugin:import/recommended"
],
"parser": "@typescript-eslint/parser",
"plugins": [], // Only use "plugins" with customize rules
"rules": {
"react/react-in-jsx-scope": "off",
"react/prop-types": "off",
"react-hooks/exhaustive-deps": "error",
"@typescript-eslint/ban-types": "error",
"@typescript-eslint/no-unused-vars": "error",
"@typescript-eslint/no-explicit-any": "error",
"@next/next/no-img-element": "off"
}
}
See more TSConfig references: docs
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"allowUnreachableCode": false,
"skipLibCheck": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"useDefineForClassFields": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"importsNotUsedAsValues": "error",
"baseUrl": ".",
"paths": {
"~/*": ["src/*"]
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
}
Using Eslint and Stylelint checks
module.exports = {
"./src/**/*.(ts|tsx|js|jsx)": (filenames) =>
`npx eslint ${filenames.join(" ")}`,
"./src/**/*.(css|scss|sass)": (filenames) =>
`npx stylelint ${filenames.join(" ")}`,
};
Read docs: Configurations and Rules
module.exports = {
extends: ["@commitlint/config-conventional"],
rules: {
"type-case": [2, "always", "lower-case"],
"type-empty": [2, "never"],
"type-enum": [
2,
"always",
[
"build",
"chore",
"docs",
"feat",
"fix",
"perf",
"refactor",
"revert",
"release",
"style",
"test",
],
],
},
};
Read docs: Configurations, Original rules and SCSS rules
{
"extends": ["stylelint-config-standard-scss"],
"plugins": ["stylelint-order"],
"rules": {
"value-no-vendor-prefix": true,
"declaration-colon-newline-after": null,
"value-list-comma-newline-after": null,
"font-family-name-quotes": null,
"shorthand-property-no-redundant-values": null,
"no-missing-end-of-source-newline": null,
"declaration-empty-line-before": null,
"selector-class-pattern": null,
"indentation": null,
"selector-list-comma-newline-after": "always-multi-line",
"order/properties-order": propertyOrder, // variable "propertyOrder in ".stylelintrc.js"
}
}