├── .babelrc ├── .editorconfig ├── .eslintignore ├── .eslintrc.json ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── dependabot.yml └── workflows │ └── ci.yml ├── .gitignore ├── .husky ├── .gitignore ├── commit-msg ├── pre-commit └── prepare-commit-msg ├── .jest └── setup.ts ├── .prettierignore ├── .prettierrc ├── .storybook ├── main.js └── preview.js ├── LICENSE ├── README.md ├── commitlint.config.js ├── generators ├── plopfile.js └── templates │ ├── index.tsx.hbs │ ├── stories.tsx.hbs │ ├── styles.ts.hbs │ └── test.tsx.hbs ├── jest.config.js ├── next-env.d.ts ├── next.config.js ├── package.json ├── public ├── favicon.ico ├── img │ └── nextjs.png ├── manifest.json └── vercel.svg ├── src ├── components │ └── Main │ │ ├── __snapshots__ │ │ └── test.tsx.snap │ │ ├── index.tsx │ │ ├── stories.tsx │ │ ├── styles.ts │ │ └── test.tsx ├── pages │ ├── _app.tsx │ ├── _document.tsx │ └── index.tsx └── styles │ └── global.ts ├── tsconfig.json └── yarn.lock /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["next/babel", "@babel/preset-typescript"], 3 | "plugins": [ 4 | [ 5 | "babel-plugin-styled-components", 6 | { 7 | "ssr": true, 8 | "displayName": true 9 | } 10 | ] 11 | ], 12 | "env": { 13 | "test": { 14 | "plugins": [ 15 | [ 16 | "babel-plugin-styled-components", 17 | { 18 | "ssr": false, 19 | "displayName": false 20 | } 21 | ] 22 | ] 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | indent_style = space 6 | indent_size = 2 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | !.storybook 2 | !.jest 3 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "es2020": 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": 11, 25 | "sourceType": "module" 26 | }, 27 | "plugins": [ 28 | "react", 29 | "@typescript-eslint", 30 | "react-hooks", 31 | "eslint-plugin-import-helpers" 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 | "@typescript-eslint/explicit-module-boundary-types": "off", 39 | "import-helpers/order-imports": [ 40 | "warn", 41 | { 42 | "newlinesBetween": "always", 43 | "groups": [ 44 | "/^next/", 45 | "module", 46 | "/^components/", 47 | "/^utils/", 48 | "/^styles/", 49 | ["parent", "sibling", "index"] 50 | ], 51 | "alphabetize": { "order": "asc", "ignoreCase": true } 52 | } 53 | ] 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: npm 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | time: "09:00" 8 | open-pull-requests-limit: 10 9 | ignore: 10 | - dependency-name: "@storybook/addon-essentials" 11 | versions: 12 | - 6.1.19 13 | - 6.2.4 14 | - dependency-name: "@storybook/react" 15 | versions: 16 | - 6.1.19 17 | - 6.2.1 18 | - dependency-name: styled-components 19 | versions: 20 | - 5.2.2 21 | - dependency-name: "@typescript-eslint/eslint-plugin" 22 | versions: 23 | - 4.15.2 24 | - 4.20.0 25 | - dependency-name: "@babel/core" 26 | versions: 27 | - 7.13.1 28 | - 7.13.13 29 | - dependency-name: "@testing-library/jest-dom" 30 | versions: 31 | - 5.11.10 32 | - dependency-name: eslint-plugin-react 33 | versions: 34 | - 7.23.0 35 | - dependency-name: "@typescript-eslint/parser" 36 | versions: 37 | - 4.15.2 38 | - 4.18.0 39 | - dependency-name: "@types/styled-components" 40 | versions: 41 | - 5.1.8 42 | - dependency-name: typescript 43 | versions: 44 | - 4.1.4 45 | - 4.2.2 46 | - dependency-name: "@commitlint/cli" 47 | versions: 48 | - 12.0.0 49 | - 12.0.1 50 | - dependency-name: "@babel/preset-env" 51 | versions: 52 | - 7.12.17 53 | - 7.13.0 54 | - 7.13.5 55 | - 7.13.8 56 | - dependency-name: husky 57 | versions: 58 | - 5.0.9 59 | - 5.1.1 60 | - 5.1.2 61 | - dependency-name: "@commitlint/config-conventional" 62 | versions: 63 | - 12.0.0 64 | - dependency-name: "@babel/preset-typescript" 65 | versions: 66 | - 7.12.17 67 | - dependency-name: "@types/node" 68 | versions: 69 | - 14.14.26 70 | - 14.14.30 71 | - dependency-name: "@types/react" 72 | versions: 73 | - 17.0.1 74 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: ci 2 | on: [pull_request] 3 | 4 | jobs: 5 | build: 6 | runs-on: ubuntu-latest 7 | steps: 8 | - name: Checkout Repository 9 | uses: actions/checkout@v2 10 | 11 | - name: Setup Node 12 | uses: actions/setup-node@v1 13 | with: 14 | node-version: 14.x 15 | 16 | - uses: actions/cache@v2 17 | id: yarn-cache 18 | with: 19 | path: | 20 | ~/cache 21 | !~/cache/exclude 22 | **/node_modules 23 | key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} 24 | restore-keys: | 25 | ${{ runner.os }}-yarn- 26 | 27 | - name: Install dependencies 28 | run: yarn install 29 | 30 | - name: Linting 31 | run: yarn lint 32 | 33 | - name: Typecheck 34 | run: yarn typecheck 35 | 36 | - name: Test 37 | run: yarn test 38 | 39 | - name: Build 40 | run: yarn build 41 | -------------------------------------------------------------------------------- /.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 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | 21 | # debug 22 | npm-debug.log* 23 | yarn-debug.log* 24 | yarn-error.log* 25 | 26 | # local env files 27 | .env.local 28 | .env.development.local 29 | .env.test.local 30 | .env.production.local 31 | 32 | # sw 33 | public/sw.js 34 | public/workbox-*.js 35 | public/sw.js.map 36 | public/workbox-*.js.map 37 | 38 | # ts 39 | tsconfig.tsbuildinfo 40 | -------------------------------------------------------------------------------- /.husky/.gitignore: -------------------------------------------------------------------------------- 1 | _ 2 | -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | npx --no-install commitlint --edit $1 5 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | npx --no-install lint-staged 5 | -------------------------------------------------------------------------------- /.husky/prepare-commit-msg: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | exec < /dev/tty && npx cz --hook || true 5 | -------------------------------------------------------------------------------- /.jest/setup.ts: -------------------------------------------------------------------------------- 1 | import '@testing-library/jest-dom'; 2 | import 'jest-styled-components'; 3 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | !.storybook 2 | !.jest 3 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "trailingComma": "none", 3 | "semi": true, 4 | "singleQuote": true 5 | } 6 | -------------------------------------------------------------------------------- /.storybook/main.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | stories: ['../src/components/**/stories.tsx'], 3 | addons: ['@storybook/addon-essentials'] 4 | }; 5 | -------------------------------------------------------------------------------- /.storybook/preview.js: -------------------------------------------------------------------------------- 1 | import { RouterContext } from 'next/dist/shared/lib/router-context'; 2 | 3 | import GlobalStyles from '../src/styles/global'; 4 | 5 | export const parameters = { 6 | nextRouter: { 7 | Provider: RouterContext.Provider 8 | } 9 | }; 10 | export const decorators = [ 11 | (Story) => ( 12 | <> 13 | 14 | 15 | 16 | ) 17 | ]; 18 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Felipe Jung 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 |
3 | Next.js Boilerplate 4 |

5 | 6 |

7 | Simple Next.js boilerplate with lint-staged, husky, eslint + prettier, jest, commitlint + commitizen, storybook and styled-components. 8 |

9 | 10 |

11 | GitHub top language 12 | 13 | GitHub language count 14 | 15 | Repository size 16 | 17 | 18 | Commitizen friendly 19 | 20 | 21 | 22 | GitHub last commit 23 | 24 | 25 | 26 | Repository issues 27 | 28 | 29 | GitHub 30 |

31 | 32 |

33 | Technologies   |    34 | License 35 |

36 | 37 | ![Cover](https://res.cloudinary.com/dqcqifjms/image/upload/v1615131441/felipejung/nextjs-boilerplate-cover.png) 38 | 39 | ## :rocket: Technologies 40 | 41 | - [React.js](https://reactjs.org) 42 | - [Next.js](https://nextjs.org) 43 | - [lint-staged](https://github.com/okonet/lint-staged) 44 | - [husky](https://typicode.github.io/husky) 45 | - [eslint](https://eslint.org) 46 | - [prettier](https://prettier.io) 47 | - [jest](https://jestjs.io) 48 | - [commitlint](https://commitlint.js.org) 49 | - [commitizen](http://commitizen.github.io/cz-cli/) 50 | - [storybook](https://storybook.js.org) 51 | - [lint-staged](https://github.com/okonet/lint-staged) 52 | - [styled-components](https://www.styled-components.com) 53 | - [next-pwa](https://github.com/shadowwalker/next-pwa) 54 | - [plop](https://plopjs.com) 55 | 56 | ## :information_source: How To Use 57 | 58 | To use this template you can simply click in **[Use this template](https://github.com/felipe-jm/nextjs-boilerplate/generate)** or create your Next.js app based on this template by running: 59 | 60 | ```bash 61 | yarn create next-app -e https://github.com/felipe-jm/nextjs-boilerplate 62 | ``` 63 | 64 | ## :gear: Generating components 65 | 66 | ```bash 67 | yarn generate Button 68 | ``` 69 | 70 | Result: 71 | 72 | ``` 73 | └── components 74 | └── Button 75 | ├── index.tsx 76 | ├── stories.tsx 77 | ├── styles.ts 78 | └── test.tsx 79 | ``` 80 | 81 | ## 🤝 Contributing 82 | 83 | 1. Fork this repository; 84 | 2. Create your branch: `git checkout -b my-awesome-contribution`; 85 | 3. Commit your changes: `git commit -m 'Add some awesome contribution'`; 86 | 4. Push to the branch: `git push origin my-awesome-contribution`. 87 | 88 | **After your pull request is merged**, you can safely delete your branch. 89 | 90 | ## :memo: License 91 | 92 | This project is under the MIT license. See the [LICENSE](https://github.com/felipe-jm/nextjs-boilerplate/blob/master/LICENSE) for more information. 93 | 94 | --- 95 | 96 | Made with much :heart: and :muscle: by Felipe Jung :blush: My Contact 97 | -------------------------------------------------------------------------------- /commitlint.config.js: -------------------------------------------------------------------------------- 1 | module.exports = {extends: ['@commitlint/config-conventional']} 2 | -------------------------------------------------------------------------------- /generators/plopfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function (plop) { 2 | plop.setGenerator('component', { 3 | description: 'Application Component', 4 | prompts: [ 5 | { 6 | type: 'input', 7 | name: 'name', 8 | message: 'Component name?' 9 | } 10 | ], 11 | actions: [ 12 | { 13 | type: 'add', 14 | path: '../src/components/{{pascalCase name}}/index.tsx', 15 | templateFile: 'templates/index.tsx.hbs' 16 | }, 17 | { 18 | type: 'add', 19 | path: '../src/components/{{pascalCase name}}/styles.tsx', 20 | templateFile: 'templates/styles.ts.hbs' 21 | }, 22 | { 23 | type: 'add', 24 | path: '../src/components/{{pascalCase name}}/stories.tsx', 25 | templateFile: 'templates/stories.tsx.hbs' 26 | }, 27 | { 28 | type: 'add', 29 | path: '../src/components/{{pascalCase name}}/test.tsx', 30 | templateFile: 'templates/test.tsx.hbs' 31 | } 32 | ] 33 | }); 34 | }; 35 | -------------------------------------------------------------------------------- /generators/templates/index.tsx.hbs: -------------------------------------------------------------------------------- 1 | import { Wrapper, Logo, Title, Description } from './styles'; 2 | 3 | const {{pascalCase name}} = () => ( 4 | 5 |

6 |
7 | ); 8 | 9 | export default {{pascalCase name}}; 10 | -------------------------------------------------------------------------------- /generators/templates/stories.tsx.hbs: -------------------------------------------------------------------------------- 1 | import { Story, Meta } from '@storybook/react/types-6-0'; 2 | 3 | import {{pascalCase name}} from '.'; 4 | 5 | export default { 6 | title: '{{pascalCase name}}', 7 | component: {{pascalCase name}} 8 | } as Meta; 9 | 10 | export const Basic: Story = () => <{{pascalCase name}} />; 11 | -------------------------------------------------------------------------------- /generators/templates/styles.ts.hbs: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | export const Wrapper = styled.main``; 4 | -------------------------------------------------------------------------------- /generators/templates/test.tsx.hbs: -------------------------------------------------------------------------------- 1 | import { render, screen } from '@testing-library/react'; 2 | 3 | import {{pascalCase name}} from '.'; 4 | 5 | describe('<{{pascalCase name}} />', () => { 6 | it('should render the heading', () => { 7 | const { container } = render(<{{pascalCase name}} />); 8 | 9 | expect( 10 | screen.getByRole('heading', { name: /{{pascalCase name}}/i }) 11 | ).toBeInTheDocument(); 12 | 13 | expect(container.firstChild).toMatchSnapshot(); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | testEnvironment: 'jsdom', 3 | testPathIgnorePatterns: ['/node_modules/', '/.next/'], 4 | collectCoverage: true, 5 | collectCoverageFrom: ['src/**/*.ts(x)?', '!src/**/stories.tsx'], 6 | setupFilesAfterEnv: ['/.jest/setup.ts'], 7 | modulePaths: ['/src/'] 8 | }; 9 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /next.config.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line @typescript-eslint/no-var-requires 2 | const withPWA = require('next-pwa')({ 3 | dest: 'public' 4 | }); 5 | const isProduction = process.env.NODE_ENV === 'production'; 6 | 7 | module.exports = withPWA({ 8 | pwa: { 9 | dest: 'public', 10 | disable: !isProduction 11 | } 12 | }); 13 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-avancado-boilerplate", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "eslint src --max-warnings=0", 10 | "next:lint": "next lint", 11 | "typecheck": "tsc --project tsconfig.json --noEmit", 12 | "test": "jest", 13 | "test:watch": "jest --watch", 14 | "generate": "yarn plop --plopfile ./generators/plopfile.js", 15 | "storybook": "start-storybook -s ./public -p 6006", 16 | "build-storybook": "build-storybook -s ./public", 17 | "prepare": "husky install" 18 | }, 19 | "lint-staged": { 20 | "src/**/*": [ 21 | "yarn lint --fix", 22 | "yarn test --findRelatedTests --bail" 23 | ] 24 | }, 25 | "dependencies": { 26 | "next": "13.3.1", 27 | "next-pwa": "^5.6.0", 28 | "react": "18.2.0", 29 | "react-dom": "18.2.0", 30 | "styled-components": "^5.3.11" 31 | }, 32 | "devDependencies": { 33 | "@babel/core": "^7.22.10", 34 | "@babel/preset-env": "^7.22.10", 35 | "@babel/preset-typescript": "^7.22.5", 36 | "@commitlint/cli": "^17.7.1", 37 | "@commitlint/config-conventional": "^17.7.0", 38 | "@storybook/addon-essentials": "7.3.2", 39 | "@storybook/react": "6.5.16", 40 | "@testing-library/jest-dom": "^5.17.0", 41 | "@testing-library/react": "^14.0.0", 42 | "@types/jest": "^29.5.3", 43 | "@types/node": "^20.5.1", 44 | "@types/react": "^18.2.20", 45 | "@types/styled-components": "^5.1.26", 46 | "@typescript-eslint/eslint-plugin": "^5.62.0", 47 | "@typescript-eslint/parser": "^5.62.0", 48 | "babel-jest": "^29.6.2", 49 | "babel-loader": "^9.1.3", 50 | "babel-plugin-styled-components": "^2.1.4", 51 | "commitizen": "^4.3.0", 52 | "cz-conventional-changelog": "3.3.0", 53 | "eslint": "^8.47.0", 54 | "eslint-config-next": "^13.4.12", 55 | "eslint-config-prettier": "^9.0.0", 56 | "eslint-plugin-import-helpers": "^1.3.1", 57 | "eslint-plugin-prettier": "^4.2.1", 58 | "eslint-plugin-react": "^7.33.2", 59 | "eslint-plugin-react-hooks": "^4.6.0", 60 | "husky": "^8.0.3", 61 | "jest": "^29.6.2", 62 | "jest-environment-jsdom": "^29.6.3", 63 | "jest-styled-components": "^7.1.1", 64 | "lint-staged": "^13.2.3", 65 | "plop": "^3.1.2", 66 | "prettier": "^2.8.8", 67 | "typescript": "^5.1.6" 68 | }, 69 | "config": { 70 | "commitizen": { 71 | "path": "./node_modules/cz-conventional-changelog" 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felipe-jm/nextjs-boilerplate/42871a900a5fcdc37bf86322bc90f786ffe07a49/public/favicon.ico -------------------------------------------------------------------------------- /public/img/nextjs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felipe-jm/nextjs-boilerplate/42871a900a5fcdc37bf86322bc90f786ffe07a49/public/img/nextjs.png -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "React Avançado - Boilerplate", 3 | "short_name": "React Avançado", 4 | "icons": [ 5 | { 6 | "src": "/img/icon-192.png", 7 | "type": "image/png", 8 | "sizes": "192x192" 9 | }, 10 | { 11 | "src": "/img/icon-512.png", 12 | "type": "image/png", 13 | "sizes": "512x512" 14 | } 15 | ], 16 | "theme_color": "#FFFFFF", 17 | "background_color": "#06092b", 18 | "description": "Simple Next.js boilerplate with lint-staged, husky, eslint + prettier, jest, storybook and styled-components", 19 | "start_url": "/", 20 | "display": "fullscreen", 21 | "orientation": "portrait" 22 | } 23 | -------------------------------------------------------------------------------- /public/vercel.svg: -------------------------------------------------------------------------------- 1 | 3 | 4 | -------------------------------------------------------------------------------- /src/components/Main/__snapshots__/test.tsx.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`
should render the heading 1`] = ` 4 | .c0 { 5 | color: #696969; 6 | width: 100%; 7 | height: 100%; 8 | padding: 3rem; 9 | display: -webkit-box; 10 | display: -webkit-flex; 11 | display: -ms-flexbox; 12 | display: flex; 13 | -webkit-flex-direction: column; 14 | -ms-flex-direction: column; 15 | flex-direction: column; 16 | text-align: center; 17 | -webkit-align-items: center; 18 | -webkit-box-align: center; 19 | -ms-flex-align: center; 20 | align-items: center; 21 | -webkit-box-pack: center; 22 | -webkit-justify-content: center; 23 | -ms-flex-pack: center; 24 | justify-content: center; 25 | background-color: #fff; 26 | } 27 | 28 | .c1 { 29 | height: 36rem; 30 | margin-bottom: 2rem; 31 | } 32 | 33 | .c2 { 34 | font-size: 5rem; 35 | } 36 | 37 | .c3 { 38 | font-size: 4rem; 39 | font-weight: 400; 40 | } 41 | 42 |
45 | Next.js Logo in the screen center 50 |

53 | Next.js Boilerplate 54 |

55 |

58 | Typescript, React.js, Next.js and Styled Components 59 |

60 |
61 | `; 62 | -------------------------------------------------------------------------------- /src/components/Main/index.tsx: -------------------------------------------------------------------------------- 1 | import { Wrapper, Logo, Title, Description } from './styles'; 2 | 3 | const Main = ({ 4 | title = 'Next.js Boilerplate', 5 | description = 'Typescript, React.js, Next.js and Styled Components' 6 | }) => ( 7 | 8 | 9 | 10 | {title} 11 | {description} 12 | 13 | ); 14 | 15 | export default Main; 16 | -------------------------------------------------------------------------------- /src/components/Main/stories.tsx: -------------------------------------------------------------------------------- 1 | import { Story, Meta } from '@storybook/react/types-6-0'; 2 | 3 | import Main from '.'; 4 | 5 | export default { 6 | title: 'Main', 7 | component: Main 8 | } as Meta; 9 | 10 | export const Basic: Story = (args) =>
; 11 | -------------------------------------------------------------------------------- /src/components/Main/styles.ts: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | export const Wrapper = styled.main` 4 | color: #696969; 5 | width: 100%; 6 | height: 100%; 7 | padding: 3rem; 8 | 9 | display: flex; 10 | flex-direction: column; 11 | text-align: center; 12 | align-items: center; 13 | justify-content: center; 14 | 15 | background-color: #fff; 16 | `; 17 | 18 | export const Logo = styled.img` 19 | height: 36rem; 20 | margin-bottom: 2rem; 21 | `; 22 | 23 | export const Title = styled.h1` 24 | font-size: 5rem; 25 | `; 26 | 27 | export const Description = styled.p` 28 | font-size: 4rem; 29 | font-weight: 400; 30 | `; 31 | -------------------------------------------------------------------------------- /src/components/Main/test.tsx: -------------------------------------------------------------------------------- 1 | import { render, screen } from '@testing-library/react'; 2 | 3 | import Main from '.'; 4 | 5 | describe('
', () => { 6 | it('should render the heading', () => { 7 | const { container } = render(
); 8 | 9 | expect( 10 | screen.getByRole('heading', { name: /Next.js/i }) 11 | ).toBeInTheDocument(); 12 | 13 | expect(container.firstChild).toMatchSnapshot(); 14 | }); 15 | 16 | it('should render the colors correctly', () => { 17 | const { container } = render(
); 18 | 19 | expect(container.firstChild).toHaveStyle({ 20 | 'background-color': '#fff' 21 | }); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /src/pages/_app.tsx: -------------------------------------------------------------------------------- 1 | import { AppProps } from 'next/app'; 2 | import Head from 'next/head'; 3 | 4 | import GlobalStyles from 'styles/global'; 5 | 6 | function App({ Component, pageProps }: AppProps) { 7 | return ( 8 | <> 9 | 10 | Next.js - Boilerplate 11 | 12 | 16 | 17 | 18 | 19 | 20 | 21 | ); 22 | } 23 | 24 | export default App; 25 | -------------------------------------------------------------------------------- /src/pages/_document.tsx: -------------------------------------------------------------------------------- 1 | import Document, { 2 | DocumentContext, 3 | Html, 4 | Head, 5 | Main, 6 | NextScript 7 | } from 'next/document'; 8 | 9 | import { ServerStyleSheet } from 'styled-components'; 10 | 11 | export default class MyDocument extends Document { 12 | static async getInitialProps(ctx: DocumentContext) { 13 | const sheet = new ServerStyleSheet(); 14 | const originalRenderPage = ctx.renderPage; 15 | 16 | try { 17 | ctx.renderPage = () => 18 | originalRenderPage({ 19 | enhanceApp: (App) => 20 | function enhance(props) { 21 | return sheet.collectStyles(); 22 | } 23 | }); 24 | 25 | const initialProps = await Document.getInitialProps(ctx); 26 | return { 27 | ...initialProps, 28 | styles: ( 29 | <> 30 | {initialProps.styles} 31 | {sheet.getStyleElement()} 32 | 33 | ) 34 | }; 35 | } finally { 36 | sheet.seal(); 37 | } 38 | } 39 | 40 | render() { 41 | return ( 42 | 43 | 44 | 45 |
46 | 47 | 48 | 49 | ); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/pages/index.tsx: -------------------------------------------------------------------------------- 1 | import Main from 'components/Main'; 2 | 3 | const Home = () =>
; 4 | 5 | export default Home; 6 | -------------------------------------------------------------------------------- /src/styles/global.ts: -------------------------------------------------------------------------------- 1 | import { createGlobalStyle } from 'styled-components'; 2 | 3 | const GlobalStyles = createGlobalStyle` 4 | * { 5 | margin: 0; 6 | padding: 0; 7 | box-sizing: border-box; 8 | } 9 | 10 | html { 11 | font-size: 62.5%; 12 | } 13 | 14 | html, body, #__next { 15 | height: 100%; 16 | } 17 | 18 | body { 19 | font-family: ---apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, 20 | Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif 21 | } 22 | `; 23 | 24 | export default GlobalStyles; 25 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": "src", 4 | "target": "es5", 5 | "lib": [ 6 | "dom", 7 | "dom.iterable", 8 | "esnext" 9 | ], 10 | "allowJs": true, 11 | "skipLibCheck": true, 12 | "strict": true, 13 | "forceConsistentCasingInFileNames": true, 14 | "noEmit": true, 15 | "esModuleInterop": true, 16 | "module": "esnext", 17 | "moduleResolution": "node", 18 | "resolveJsonModule": true, 19 | "isolatedModules": true, 20 | "jsx": "preserve", 21 | "incremental": true 22 | }, 23 | "exclude": [ 24 | "node_modules" 25 | ], 26 | "include": [ 27 | "next-env.d.ts", 28 | "**/*.ts", 29 | "**/*.tsx" 30 | ] 31 | } 32 | --------------------------------------------------------------------------------