├── src
├── hooks
│ └── .gitkeep
├── configs
│ └── .gitkeep
├── services
│ └── .gitkeep
├── components
│ └── Main
│ │ ├── index.tsx
│ │ ├── Main.tsx
│ │ ├── Main.stories.tsx
│ │ └── Main.spec.tsx
├── types
│ ├── .editorconfig
│ ├── styled-components.d.ts
│ └── jest-styled-components.d.ts
├── app
│ ├── page.tsx
│ ├── head.tsx
│ ├── styles.ts
│ ├── layout.tsx
│ └── lib
│ │ └── registry.tsx
└── common
│ └── styles
│ ├── global.ts
│ └── theme.ts
├── public
├── robots.txt
└── favicon.ico
├── .prettierrc
├── .github
└── architecture.png
├── .husky
└── pre-commit
├── .storybook
├── preview.js
└── main.js
├── .vscode
└── settings.json
├── next.config.js
├── .eslintignore
├── next-env.d.ts
├── .jest
└── setup.js
├── .gitignore
├── tsconfig.json
├── jest.config.js
├── .eslintrc.json
├── package.json
└── README.md
/src/hooks/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/configs/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/services/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | User-Agent: *
2 | Allow: /
3 |
4 |
--------------------------------------------------------------------------------
/src/components/Main/index.tsx:
--------------------------------------------------------------------------------
1 | export * from './Main';
2 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "semi": true,
3 | "singleQuote": true
4 | }
5 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/imperadorxs/nextjs-13-boilerplate/HEAD/public/favicon.ico
--------------------------------------------------------------------------------
/.github/architecture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/imperadorxs/nextjs-13-boilerplate/HEAD/.github/architecture.png
--------------------------------------------------------------------------------
/.husky/pre-commit:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 | . "$(dirname -- "$0")/_/husky.sh"
3 |
4 | npx --no-install lint-staged
5 |
--------------------------------------------------------------------------------
/.storybook/preview.js:
--------------------------------------------------------------------------------
1 |
2 | export const decorators = [
3 | (Story) => (
4 | <>
5 |
6 | >
7 | )
8 | ]
9 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "typescript.tsdk": "node_modules/typescript/lib",
3 | "typescript.enablePromptUseWorkspaceTsdk": true
4 | }
--------------------------------------------------------------------------------
/src/components/Main/Main.tsx:
--------------------------------------------------------------------------------
1 | export function Main() {
2 | return (
3 |
4 |
nextjs template
5 |
6 | );
7 | }
8 |
--------------------------------------------------------------------------------
/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | experimental: {
4 | appDir: true,
5 | }
6 | }
7 |
8 | module.exports = nextConfig
9 |
--------------------------------------------------------------------------------
/src/types/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | indent_style = space
5 | indent_size = 2
6 | end_of_line = lf
7 | charset = utf-8
8 | trim_trailing_whitespace = true
9 | insert_final_newline = true
10 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | **/*.js
2 | node_modules
3 | build
4 | /src/react-app-env.d.ts
5 | /src/reportWebVitals.ts
6 | /src/components/Archievements
7 | /src/sections/Achievements
8 | *.js
9 | .next
10 | **/*.mdx
11 | **/*.png
12 |
--------------------------------------------------------------------------------
/next-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 |
4 | // NOTE: This file should not be edited
5 | // see https://nextjs.org/docs/basic-features/typescript for more information.
6 |
--------------------------------------------------------------------------------
/src/app/page.tsx:
--------------------------------------------------------------------------------
1 | 'use client';
2 |
3 | import * as S from './styles';
4 |
5 | export default function Home() {
6 | return (
7 |
8 | Next 13 boilerplate
9 |
10 | );
11 | }
12 |
--------------------------------------------------------------------------------
/src/components/Main/Main.stories.tsx:
--------------------------------------------------------------------------------
1 | import { Story, Meta } from '@storybook/react/types-6-0';
2 | import { Main } from './index';
3 |
4 | export default {
5 | title: 'Main',
6 | component: Main,
7 | } as Meta;
8 |
9 | export const Default: Story = (args) => ;
10 |
--------------------------------------------------------------------------------
/.jest/setup.js:
--------------------------------------------------------------------------------
1 | // Optional: configure or set up a testing framework before each test.
2 | // If you delete this file, remove `setupFilesAfterEnv` from `jest.config.js`
3 |
4 | // Used for __tests__/testing-library.js
5 | // Learn more: https://github.com/testing-library/jest-dom
6 | import '@testing-library/jest-dom/extend-expect'
7 |
--------------------------------------------------------------------------------
/src/types/styled-components.d.ts:
--------------------------------------------------------------------------------
1 | import 'styled-components';
2 | import { theme } from '../common/styles/theme';
3 |
4 | type Theme = typeof theme;
5 |
6 | declare module 'styled-components' {
7 | // eslint-disable-next-line @typescript-eslint/no-empty-interface
8 | export interface DefaultTheme extends Theme {}
9 | }
10 |
--------------------------------------------------------------------------------
/src/app/head.tsx:
--------------------------------------------------------------------------------
1 | export default function Head() {
2 | return (
3 | <>
4 | Create Next App
5 |
6 |
7 |
8 | >
9 | );
10 | }
11 |
--------------------------------------------------------------------------------
/src/app/styles.ts:
--------------------------------------------------------------------------------
1 | import styled, { css } from 'styled-components';
2 |
3 | export const Wrapper = styled.div`
4 | ${({ theme }) => css`
5 | height: 100vh;
6 | width: 100vw;
7 | display: grid;
8 | place-items: center;
9 |
10 | h1 {
11 | font-size: 5rem;
12 | font-weight: 400;
13 | }
14 | background-color: ${theme.colors.black};
15 | `}
16 | `;
17 |
--------------------------------------------------------------------------------
/src/components/Main/Main.spec.tsx:
--------------------------------------------------------------------------------
1 | import { render, screen } from '@testing-library/react';
2 |
3 | import { Main } from './index';
4 |
5 | describe('', () => {
6 | it('should render the heading', () => {
7 | const { container } = render();
8 |
9 | expect(
10 | screen.getByRole('heading', { name: /nextjs template/i })
11 | ).toBeInTheDocument();
12 | });
13 | });
14 |
--------------------------------------------------------------------------------
/.storybook/main.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | "stories": [
3 | "../src/**/*.stories.mdx",
4 | "../src/**/*.stories.@(js|jsx|ts|tsx)"
5 | ],
6 | "addons": [
7 | "@storybook/addon-links",
8 | "@storybook/addon-essentials",
9 | "@storybook/addon-interactions"
10 | ],
11 | webpackFinal: (config) => {
12 | config.resolve.modules.push(`${process.cwd()}/src`)
13 | return config
14 | },
15 | "framework": "@storybook/react"
16 | }
17 |
--------------------------------------------------------------------------------
/src/common/styles/global.ts:
--------------------------------------------------------------------------------
1 | import { createGlobalStyle, css } from 'styled-components';
2 |
3 | export const GlobalStyles = createGlobalStyle`
4 | * {
5 | margin: 0;
6 | padding: 0;
7 | box-sizing: border-box;
8 | }
9 |
10 | ${({ theme }) => css`
11 | html {
12 | font-size: 62.5%; // 1rem to equal 10px
13 | }
14 |
15 | html,
16 | body {
17 | height: 100%;
18 | background-color: #333;
19 | color: #ccc;
20 | }
21 | `}
22 |
23 |
24 | `;
25 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 | .env
8 | # pwa
9 | public/sw.js
10 | public/workbox-*.js
11 |
12 | # testing
13 | /coverage
14 |
15 | # next.js
16 | /.next/
17 | /out/
18 |
19 | # production
20 | /build
21 |
22 | # misc
23 | .DS_Store
24 | *.pem
25 |
26 | # debug
27 | npm-debug.log*
28 | yarn-debug.log*
29 | yarn-error.log*
30 | .pnpm-debug.log*
31 |
32 | # local env files
33 | .env*.local
34 |
35 | # vercel
36 | .vercel
37 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "strict": true,
8 | "forceConsistentCasingInFileNames": true,
9 | "noEmit": true,
10 | "esModuleInterop": true,
11 | "module": "esnext",
12 | "moduleResolution": "node",
13 | "resolveJsonModule": true,
14 | "isolatedModules": true,
15 | "jsx": "preserve",
16 | "incremental": true,
17 | "plugins": [
18 | {
19 | "name": "next"
20 | }
21 | ],
22 | "baseUrl": ".",
23 | "paths": {
24 | "@/*": ["./src/*"]
25 | }
26 | },
27 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
28 | "exclude": ["node_modules"]
29 | }
30 |
--------------------------------------------------------------------------------
/jest.config.js:
--------------------------------------------------------------------------------
1 | const nextJest = require('next/jest')
2 |
3 | const createJestConfig = nextJest({
4 | // Provide the path to your Next.js app to load next.config.js and .env files in your test environment
5 | dir: './',
6 | })
7 |
8 | // Add any custom config to be passed to Jest
9 | const customJestConfig = {
10 | setupFilesAfterEnv: ['/.jest/setup.js'],
11 | modulePaths: ['/src/', '/.jest'],
12 | moduleNameMapper: {
13 | '^styled-components':
14 | '/node_modules/styled-components/dist/styled-components.browser.cjs.js'
15 | },
16 | testEnvironment: 'jest-environment-jsdom',
17 | }
18 |
19 | // createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async
20 | module.exports = createJestConfig(customJestConfig)
21 |
--------------------------------------------------------------------------------
/src/app/layout.tsx:
--------------------------------------------------------------------------------
1 | 'use client';
2 |
3 | import StyledComponentsRegistry from './lib/registry';
4 | import { ThemeProvider } from 'styled-components';
5 |
6 | import { GlobalStyles } from '@/common/styles/global';
7 | import { theme } from '@/common/styles/theme';
8 |
9 | export default function RootLayout({
10 | children,
11 | }: {
12 | children: React.ReactNode;
13 | }) {
14 | return (
15 |
16 | {/*
17 | will contain the components returned by the nearest parent
18 | head.tsx. Find out more at https://beta.nextjs.org/docs/api-reference/file-conventions/head
19 | */}
20 |
21 |
22 |
23 | <>
24 |
25 | {children}
26 | >
27 |
28 |
29 |
30 | );
31 | }
32 |
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "browser": true,
4 | "es2021": true,
5 | "jest": true,
6 | "node": true
7 | },
8 | "settings": {
9 | "react": {
10 | "version": "detect"
11 | }
12 | },
13 | "extends": [
14 | "eslint:recommended",
15 | "plugin:react/recommended",
16 | "plugin:@typescript-eslint/recommended",
17 | "plugin:prettier/recommended"
18 | ],
19 | "parser": "@typescript-eslint/parser",
20 | "parserOptions": {
21 | "ecmaFeatures": {
22 | "jsx": true
23 | },
24 | "ecmaVersion": "latest",
25 | "sourceType": "module"
26 | },
27 | "plugins": [
28 | "react",
29 | "@typescript-eslint",
30 | "react-hooks",
31 | "prettier"
32 | ],
33 | "rules": {
34 | "react-hooks/rules-of-hooks": "error",
35 | "react-hooks/exhaustive-deps": "warn",
36 | "react/prop-types": "off",
37 | "react/react-in-jsx-scope": "off",
38 | "prettier/prettier": "error"
39 | }
40 | }
--------------------------------------------------------------------------------
/src/types/jest-styled-components.d.ts:
--------------------------------------------------------------------------------
1 | // Types provided from the official repo:
2 | // https://github.com/styled-components/jest-styled-components/blob/master/typings/index.d.ts
3 |
4 | /* eslint-disable @typescript-eslint/no-explicit-any */
5 | /* eslint-disable @typescript-eslint/ban-types */
6 | import { Plugin, NewPlugin } from 'pretty-format';
7 |
8 | declare global {
9 | namespace jest {
10 | interface AsymmetricMatcher {
11 | $$typeof: symbol;
12 | sample?: string | RegExp | object | Array | Function;
13 | }
14 |
15 | type Value = string | number | RegExp | AsymmetricMatcher | undefined;
16 |
17 | interface Options {
18 | media?: string;
19 | modifier?: string;
20 | supports?: string;
21 | }
22 |
23 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
24 | interface Matchers {
25 | toHaveStyleRule(property: string, value?: Value, options?: Options): R;
26 | }
27 | }
28 | }
29 |
30 | export declare const styleSheetSerializer: Exclude;
31 |
--------------------------------------------------------------------------------
/src/app/lib/registry.tsx:
--------------------------------------------------------------------------------
1 | /* eslint-disable @typescript-eslint/ban-ts-comment */
2 | 'use client';
3 | import React, { useState } from 'react';
4 | import { useServerInsertedHTML } from 'next/navigation';
5 | import { ServerStyleSheet, StyleSheetManager } from 'styled-components';
6 |
7 | export default function StyledComponentsRegistry({
8 | children,
9 | }: {
10 | children: React.ReactNode;
11 | }) {
12 | // Only create stylesheet once with lazy initial state
13 | // x-ref: https://reactjs.org/docs/hooks-reference.html#lazy-initial-state
14 | const [styledComponentsStyleSheet] = useState(() => new ServerStyleSheet());
15 |
16 | useServerInsertedHTML(() => {
17 | const styles = styledComponentsStyleSheet.getStyleElement();
18 | //@ts-ignore
19 | styledComponentsStyleSheet.instance.clearTag();
20 | return <>{styles}>;
21 | });
22 |
23 | if (typeof window !== 'undefined') return <>{children}>;
24 |
25 | return (
26 |
27 | {children}
28 |
29 | );
30 | }
31 |
--------------------------------------------------------------------------------
/src/common/styles/theme.ts:
--------------------------------------------------------------------------------
1 | export const theme = {
2 | grid: {
3 | container: '130rem',
4 | gutter: '3.2rem',
5 | },
6 | border: {
7 | radius: '0.4rem',
8 | },
9 | font: {
10 | family:
11 | "Poppins, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif",
12 | light: 300,
13 | normal: 400,
14 | bold: 600,
15 | sizes: {
16 | xsmall: '1.2rem',
17 | small: '1.4rem',
18 | medium: '1.6rem',
19 | large: '1.8rem',
20 | xlarge: '2.0rem',
21 | xxlarge: '2.8rem',
22 | },
23 | },
24 | colors: {
25 | primary: '#F231A5',
26 | secondary: '#3CD3C1',
27 | mainBg: '#06092B',
28 | white: '#FAFAFA',
29 | black: '#030517',
30 | lightGray: '#EAEAEA',
31 | gray: '#8F8F8F',
32 | darkGray: '#2E2F42',
33 | },
34 | spacings: {
35 | xxsmall: '0.8rem',
36 | xsmall: '1.6rem',
37 | small: '2.4rem',
38 | medium: '3.2rem',
39 | large: '4.0rem',
40 | xlarge: '4.8rem',
41 | xxlarge: '5.6rem',
42 | },
43 | layers: {
44 | base: 10,
45 | menu: 20,
46 | overlay: 30,
47 | modal: 40,
48 | alwaysOnTop: 50,
49 | },
50 | };
51 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "nextjs-13-boilerplate",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev",
7 | "build": "next build",
8 | "start": "next start",
9 | "prepare": "husky install",
10 | "lint": "next lint",
11 | "test": "jest",
12 | "test:watch": "yarn test --watch",
13 | "storybook": "start-storybook -s ./public -p 6006",
14 | "build-storybook": "build-storybook -s ./public"
15 | },
16 | "lint-staged": {
17 | "src/**/*": [
18 | "yarn test --findRelatedTests --passWithNoTests --bail"
19 | ]
20 | },
21 | "dependencies": {
22 | "@next/font": "13.1.6",
23 | "next": "13.1.6",
24 | "react": "18.2.0",
25 | "react-dom": "18.2.0",
26 | "styled-components": "^5.3.6"
27 | },
28 | "devDependencies": {
29 | "@babel/core": "^7.17.10",
30 | "@babel/preset-typescript": "^7.16.7",
31 | "@storybook/addon-actions": "^6.4.22",
32 | "@storybook/addon-essentials": "^6.4.22",
33 | "@storybook/addon-interactions": "^6.4.22",
34 | "@storybook/addon-links": "^6.4.22",
35 | "@storybook/react": "^6.4.22",
36 | "@storybook/testing-library": "^0.0.11",
37 | "@testing-library/jest-dom": "5.16.4",
38 | "@testing-library/react": "13.2.0",
39 | "@testing-library/user-event": "14.2.0",
40 | "@types/jest": "^29.4.0",
41 | "@types/node": "18.14.0",
42 | "@types/react": "18.0.28",
43 | "@types/react-dom": "18.0.11",
44 | "@types/styled-components": "^5.1.25",
45 | "@types/testing-library__jest-dom": "5.14.5",
46 | "@typescript-eslint/eslint-plugin": "^5.23.0",
47 | "@typescript-eslint/parser": "^5.23.0",
48 | "babel-loader": "^8.2.5",
49 | "babel-plugin-inline-react-svg": "^2.0.1",
50 | "babel-plugin-styled-components": "^2.0.7",
51 | "eslint": "8.34.0",
52 | "eslint-config-next": "13.1.6",
53 | "eslint-config-prettier": "^8.5.0",
54 | "eslint-plugin-prettier": "^4.0.0",
55 | "eslint-plugin-react": "^7.29.4",
56 | "eslint-plugin-react-hooks": "^4.5.0",
57 | "eslint-plugin-storybook": "^0.5.11",
58 | "husky": "^8.0.1",
59 | "jest": "28.1.0",
60 | "jest-environment-jsdom": "28.1.0",
61 | "jest-styled-components": "^7.0.8",
62 | "lint-staged": "^12.4.1",
63 | "prettier": "^2.6.2",
64 | "typescript": "4.9.5"
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | # Next.js 13 with Typescript reference architecture
28 |
29 | ## Getting Started
30 |
31 | Start your project with this template.
32 |
33 | ```bash
34 | yarn create next-app -e https://github.com/imperadorxs/nextjs-13-boilerplate
35 | ```
36 |
37 | ### How to run
38 |
39 | `npm install`
40 | `npm dev`
41 |
42 | `yarn`
43 | `yarn dev`
44 |
45 | ### How to build
46 |
47 | `npm run build`
48 |
49 | `yarn build`
50 |
51 | ### How to tests
52 |
53 | `npm test`
54 |
55 | `yarn test`
56 |
57 | # File structure
58 |
59 | **This is your source code tree:**
60 |
61 | ```
62 | src
63 | |-- common
64 | |-- assets
65 | |-- helpers
66 | |-- mocks
67 | |-- styles
68 | |-- utils
69 | |-- components
70 | |-- config
71 | |-- hooks
72 | |-- app
73 | |-- lib
74 | |-- registry
75 | |-- head.tsx
76 | |-- layout.tsx
77 | |-- page.tsx
78 | |-- services
79 | ...
80 | ```
81 |
82 | **This is your component structure:**
83 |
84 | ```
85 | ...
86 | components
87 | |-- YourComponent
88 | |-- YourComponent.tsx
89 | |-- YourComponent.spec.ts
90 | |-- YourComponent.stories.tsx
91 | |-- interfaces.ts
92 | |-- styles.ts
93 | |-- index.tsx
94 | ...
95 | ```
96 |
97 | **These are the folders and their functions:**
98 |
99 | `./common`
100 |
101 | Here are all the project assets that will be used by the application such as global styles, images, fonts, mocks, reusable functions, among others
102 |
103 | `./components`
104 |
105 | Components are presentational only elements, grouping UI items
106 |
107 | `./configs`
108 |
109 | Configs are our application's global settings files
110 |
111 | `./hooks`
112 |
113 | Hooks are functions that allow you to “plug in” to React's state and lifecycle features from functional components
114 |
115 | `./app`
116 |
117 | App is a new pages folder are mapped in routes and have all the containers needed to implement a functionality
118 |
119 | `./services`
120 |
121 | Contains all the files responsible for consuming external services, such as the axios configuration file for consuming RestFul APIs.
122 |
123 | ### More utils commands
124 |
125 | Find and fix Javascrit and TypeScript problems according to pre-defined rules
126 | `npm run lint`
127 | `yarn lint`
128 |
129 | # Advantages of using this react project template
130 |
131 | The project is already configured with:
132 |
133 | - React
134 | - Typescript
135 | - Jest
136 | - Eslint
137 | - Prettier
138 | - Styled
139 | - Husky
140 | - Storybook
141 |
142 | ### Main dependecies
143 |
144 | - [nextjs](https://nextjs.org/blog/next-13/)
145 | - [react](https://reactjs.org/)
146 | - [styled-components](https://styled-components.com/)
147 |
148 | ### Main dev dependecies
149 |
150 | - [testing-library](https://testing-library.com/)
151 | - [eslint](https://eslint.org/)
152 | - [husky](https://www.npmjs.com/package/husky)
153 | - [lint-staged](https://www.npmjs.com/package/lint-staged)
154 | - [prettier](https://prettier.io/)
155 | - [typescript](https://www.typescriptlang.org/)
156 | - [web-vitals](https://web.dev/vitals/)
157 |
--------------------------------------------------------------------------------