├── .eslintrc.json ├── .gitignore ├── README.md ├── __tests__ ├── Home.test.tsx └── Services.test.tsx ├── jest.config.js ├── jest.setup.js ├── next.config.js ├── package-lock.json ├── package.json ├── postcss.config.js ├── public ├── next.svg └── vercel.svg ├── src ├── app │ ├── about │ │ ├── error.tsx │ │ ├── loading.tsx │ │ ├── not-found.tsx │ │ └── page.tsx │ ├── contact │ │ ├── error.tsx │ │ ├── loading.tsx │ │ ├── not-found.tsx │ │ └── page.tsx │ ├── favicon.ico │ ├── globals.css │ ├── layout.tsx │ ├── login │ │ ├── error.tsx │ │ ├── loading.tsx │ │ ├── not-found.tsx │ │ └── page.tsx │ ├── page.tsx │ └── services │ │ ├── error.tsx │ │ ├── loading.tsx │ │ ├── not-found.tsx │ │ └── page.tsx └── components │ ├── Footer │ └── Footer.tsx │ ├── Navbar │ └── Navbar.tsx │ ├── Spinner │ └── Spinner.tsx │ └── index.tsx ├── tailwind.config.ts └── tsconfig.json /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next/core-web-vitals" 3 | } 4 | -------------------------------------------------------------------------------- /.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 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | 27 | # local env files 28 | .env*.local 29 | 30 | # vercel 31 | .vercel 32 | 33 | # typescript 34 | *.tsbuildinfo 35 | next-env.d.ts 36 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Next.js React.js TypeScript Tailwind CSS Jest Starter 2 | 3 | A starter template for building web applications using Next.js with TypeScript, Tailwind CSS, and Jest for testing. 4 | 5 | ## Getting Started 6 | 7 | Follow these steps to get this starter template up and running on your local machine. 8 | 9 | ### Prerequisites 10 | 11 | Make sure you have [Node.js](https://nodejs.org/) and [npm](https://www.npmjs.com/) (or [Yarn](https://yarnpkg.com/)) installed on your computer. 12 | 13 | ### Installation 14 | 15 | 1. Clone this repository to your local machine: 16 | 17 | ```bash 18 | git clone https://github.com/zied-snoussi/nextjs13-reactjs-typescript-tailwindcss-jest-starter-frontend.git 19 | ``` 20 | 21 | 2. Change into the project directory: 22 | 23 | ```bash 24 | cd nextjs13-reactjs-typescript-tailwindcss-jest-starter-frontend 25 | ``` 26 | 27 | 3. Install the project dependencies: 28 | 29 | If you're using npm: 30 | 31 | ```bash 32 | npm install 33 | ``` 34 | 35 | If you're using Yarn: 36 | 37 | ```bash 38 | yarn 39 | ``` 40 | 41 | ### Development 42 | 43 | To start the development server, run the following command: 44 | 45 | ```bash 46 | npm run dev 47 | ``` 48 | 49 | or 50 | 51 | ```bash 52 | yarn dev 53 | ``` 54 | 55 | The application will be available at [http://localhost:3000](http://localhost:3000). 56 | 57 | ### Building 58 | 59 | To build the production-ready version of the application, use the following command: 60 | 61 | ```bash 62 | npm run build 63 | ``` 64 | 65 | or 66 | 67 | ```bash 68 | yarn build 69 | ``` 70 | 71 | ### Running in Production Mode 72 | 73 | After building the application, you can start it in production mode with the following command: 74 | 75 | ```bash 76 | npm start 77 | ``` 78 | 79 | or 80 | 81 | ```bash 82 | yarn start 83 | ``` 84 | 85 | ### Linting 86 | 87 | To run ESLint for code linting, use the following command: 88 | 89 | ```bash 90 | npm run lint 91 | ``` 92 | 93 | or 94 | 95 | ```bash 96 | yarn lint 97 | ``` 98 | 99 | ### Testing 100 | 101 | Jest is used for testing. You can run the tests with: 102 | 103 | ```bash 104 | npm test 105 | ``` 106 | 107 | or 108 | 109 | ```bash 110 | yarn test 111 | ``` 112 | 113 | For watching file changes during development, use: 114 | 115 | ```bash 116 | npm run test-watch 117 | ``` 118 | 119 | or 120 | 121 | ```bash 122 | yarn test-watch 123 | ``` 124 | 125 | ## Dependencies 126 | 127 | - [@types/node](https://www.npmjs.com/package/@types/node) - TypeScript definitions for Node.js. 128 | - [@types/react](https://www.npmjs.com/package/@types/react) - TypeScript definitions for React. 129 | - [@types/react-dom](https://www.npmjs.com/package/@types/react-dom) - TypeScript definitions for ReactDOM. 130 | - [autoprefixer](https://www.npmjs.com/package/autoprefixer) - A PostCSS plugin to parse CSS and add vendor prefixes. 131 | - [eslint](https://www.npmjs.com/package/eslint) - A pluggable and configurable linter tool for identifying and fixing problems in JavaScript code. 132 | - [eslint-config-next](https://www.npmjs.com/package/eslint-config-next) - ESLint configuration for Next.js projects. 133 | - [next](https://nextjs.org/) - The React framework for production. 134 | - [postcss](https://www.npmjs.com/package/postcss) - A tool for transforming styles with JS plugins. 135 | - [react](https://reactjs.org/) - A JavaScript library for building user interfaces. 136 | - [react-dom](https://www.npmjs.com/package/react-dom) - DOM-specific methods for React. 137 | - [tailwindcss](https://tailwindcss.com/) - A utility-first CSS framework for rapidly building custom designs. 138 | - [typescript](https://www.typescriptlang.org/) - A typed superset of JavaScript that compiles to plain JavaScript. 139 | 140 | ## Dev Dependencies 141 | 142 | - [@testing-library/jest-dom](https://www.npmjs.com/package/@testing-library/jest-dom) - Custom Jest matchers for asserting on DOM elements. 143 | - [@testing-library/react](https://www.npmjs.com/package/@testing-library/react) - Simple and complete React DOM testing utilities. 144 | - [@testing-library/user-event](https://www.npmjs.com/package/@testing-library/user-event) - Fire events as if a real user were interacting with your app. 145 | - [eslint-plugin-testing-library](https://www.npmjs.com/package/eslint-plugin-testing-library) - ESLint plugin for testing-library. 146 | - [jest](https://jestjs.io/) - A JavaScript testing framework. 147 | - [jest-environment-jsdom](https://www.npmjs.com/package/jest-environment-jsdom) - Jest environment for the JSDOM. 148 | 149 | ## License 150 | 151 | This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. 152 | 153 | ## Acknowledgments 154 | 155 | - This starter template is based on Next.js, TypeScript, Tailwind CSS, and Jest. 156 | - Feel free to customize it to fit your project's needs. 157 | 158 | Happy coding! 159 | -------------------------------------------------------------------------------- /__tests__/Home.test.tsx: -------------------------------------------------------------------------------- 1 | import { render, screen } from '@testing-library/react' 2 | import Home from '@/app/page' 3 | 4 | describe('Home', () => { 5 | it('should have "Welcome to My Next.js Starter Template" text', () => { 6 | render() // ARRANGE 7 | 8 | const myElem = screen.getByText('Welcome to My Next.js Starter Template') // ACT 9 | 10 | expect(myElem).toBeInTheDocument() // ASSERT 11 | }) 12 | 13 | it('should contain the text "This is the home page of your starter template."', () => { 14 | render() // ARRANGE 15 | 16 | const myElem = screen.getByText('This is the home page of your starter template.') // ACT 17 | 18 | expect(myElem).toBeInTheDocument() // ASSERT 19 | }) 20 | 21 | it('should have a heading with the text "Fast Performance"', () => { 22 | render() // ARRANGE 23 | 24 | const myElem = screen.getByRole('heading', { 25 | name: 'Fast Performance' 26 | }) // ACT 27 | 28 | expect(myElem).toBeInTheDocument() // ASSERT 29 | }) 30 | }) 31 | -------------------------------------------------------------------------------- /__tests__/Services.test.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { render, screen } from '@testing-library/react'; 3 | import Services from '@/app/services/page'; 4 | 5 | describe('Services', () => { 6 | it('renders the heading "Our Services"', () => { 7 | render(); 8 | const heading = screen.getByText('Our Services'); 9 | expect(heading).toBeInTheDocument(); 10 | }); 11 | 12 | it('renders a list of services', () => { 13 | render(); 14 | const servicesList = screen.getByRole('list'); 15 | expect(servicesList).toBeInTheDocument(); 16 | 17 | const serviceItems = screen.getAllByRole('listitem'); 18 | expect(serviceItems).toHaveLength(4); // Assuming there are 4 service items 19 | }); 20 | 21 | it('renders service descriptions', () => { 22 | render(); 23 | const serviceDescriptions = screen.getAllByText(/Description of Service/); 24 | expect(serviceDescriptions).toHaveLength(4); // Assuming there are 4 service descriptions 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /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 | /** @type {import('jest').Config} */ 10 | const config = { 11 | // Add more setup options before each test is run 12 | setupFilesAfterEnv: ['/jest.setup.js'], 13 | testEnvironment: 'jest-environment-jsdom', 14 | preset: 'ts-jest', 15 | } 16 | 17 | // createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async 18 | module.exports = createJestConfig(config) -------------------------------------------------------------------------------- /jest.setup.js: -------------------------------------------------------------------------------- 1 | import '@testing-library/jest-dom/extend-expect' 2 | -------------------------------------------------------------------------------- /next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = {} 3 | 4 | module.exports = nextConfig 5 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nextjs13-reactjs-typescript-tailwindcss-jest-starter-frontend", 3 | "version": "0.1.0", 4 | "author": { 5 | "name": "zied-snoussi", 6 | "email": "ziedsnoussi.tn@gmail.com", 7 | "url": "https://www.zied-snoussi.me" 8 | }, 9 | "private": true, 10 | "scripts": { 11 | "dev": "next dev", 12 | "build": "next build", 13 | "start": "next start", 14 | "lint": "next lint", 15 | "test": "jest", 16 | "test-watch": "jest --watchAll" 17 | }, 18 | "dependencies": { 19 | "@types/node": "20.6.3", 20 | "@types/react": "18.2.22", 21 | "@types/react-dom": "18.2.7", 22 | "autoprefixer": "10.4.15", 23 | "eslint": "8.49.0", 24 | "eslint-config-next": "13.5.1", 25 | "next": "13.5.1", 26 | "postcss": "8.4.30", 27 | "react": "18.2.0", 28 | "react-dom": "18.2.0", 29 | "tailwindcss": "3.3.3", 30 | "typescript": "5.2.2" 31 | }, 32 | "devDependencies": { 33 | "@testing-library/jest-dom": "^5.16.5", 34 | "@testing-library/react": "^14.0.0", 35 | "@testing-library/user-event": "^14.5.1", 36 | "eslint-plugin-testing-library": "^6.0.1", 37 | "jest": "^29.7.0", 38 | "jest-environment-jsdom": "^29.7.0", 39 | "ts-jest": "^29.1.1" 40 | } 41 | } -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /public/next.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/vercel.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/about/error.tsx: -------------------------------------------------------------------------------- 1 | 'use client' // Error components must be Client Components 2 | 3 | import { useEffect } from 'react'; 4 | 5 | const Error = ({ 6 | error, 7 | reset, 8 | }: { 9 | error: Error & { digest?: string }; 10 | reset: () => void; 11 | }) => { 12 | useEffect(() => { 13 | // Log the error to an error reporting service 14 | console.error(error); 15 | }, [error]); 16 | 17 | return ( 18 |
19 |

Something went wrong!

20 | 28 |
29 | ); 30 | }; 31 | 32 | export default Error; 33 | -------------------------------------------------------------------------------- /src/app/about/loading.tsx: -------------------------------------------------------------------------------- 1 | import { Spinner } from '@/components' 2 | import React from 'react' 3 | 4 | const loading = () => { 5 | return ( 6 | <> 7 | 8 | 9 | ) 10 | } 11 | 12 | export default loading -------------------------------------------------------------------------------- /src/app/about/not-found.tsx: -------------------------------------------------------------------------------- 1 | import Link from 'next/link' 2 | import React from 'react' 3 | 4 | const NotFound = () => { 5 | return ( 6 |
7 |

Not Found

8 |

Could not find requested resource

9 | Return Home 10 |
11 | ) 12 | } 13 | 14 | export default NotFound -------------------------------------------------------------------------------- /src/app/about/page.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const About = () => { 4 | return ( 5 |
6 |
7 |

About Us

8 |

9 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam 10 | fringilla pulvinar libero, id vulputate neque sollicitudin a. 11 | Vestibulum ante ipsum primis in faucibus orci luctus et ultrices 12 | posuere cubilia Curae; Cras consectetur feugiat malesuada. 13 |

14 |
15 |
16 | ); 17 | }; 18 | 19 | export default About; 20 | -------------------------------------------------------------------------------- /src/app/contact/error.tsx: -------------------------------------------------------------------------------- 1 | 'use client' // Error components must be Client Components 2 | 3 | import { useEffect } from 'react'; 4 | 5 | const Error = ({ 6 | error, 7 | reset, 8 | }: { 9 | error: Error & { digest?: string }; 10 | reset: () => void; 11 | }) => { 12 | useEffect(() => { 13 | // Log the error to an error reporting service 14 | console.error(error); 15 | }, [error]); 16 | 17 | return ( 18 |
19 |

Something went wrong!

20 | 28 |
29 | ); 30 | }; 31 | 32 | export default Error; 33 | -------------------------------------------------------------------------------- /src/app/contact/loading.tsx: -------------------------------------------------------------------------------- 1 | import { Spinner } from '@/components' 2 | import React from 'react' 3 | 4 | const loading = () => { 5 | return ( 6 | <> 7 | 8 | 9 | ) 10 | } 11 | 12 | export default loading -------------------------------------------------------------------------------- /src/app/contact/not-found.tsx: -------------------------------------------------------------------------------- 1 | import Link from 'next/link' 2 | import React from 'react' 3 | 4 | const NotFound = () => { 5 | return ( 6 |
7 |

Not Found

8 |

Could not find requested resource

9 | Return Home 10 |
11 | ) 12 | } 13 | 14 | export default NotFound -------------------------------------------------------------------------------- /src/app/contact/page.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Contact = () => { 4 | return ( 5 |
6 |
7 |

Contact Us

8 |

9 | If you have any questions or inquiries, feel free to get in touch with 10 | us using the contact information below. 11 |

12 |
13 |

Email: example@example.com

14 |

Phone: +1 (123) 456-7890

15 |

Address: 1234 Elm Street, City, Country

16 |
17 |
18 |
19 | ); 20 | }; 21 | 22 | export default Contact; 23 | -------------------------------------------------------------------------------- /src/app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zied-snoussi/nextjs13-reactjs-typescript-tailwindcss-jest-starter-frontend/feb988463968bd9cf2df5d6aba0dcc10f1adce87/src/app/favicon.ico -------------------------------------------------------------------------------- /src/app/globals.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | :root { 6 | --foreground-rgb: 0, 0, 0; 7 | --background-start-rgb: 214, 219, 220; 8 | --background-end-rgb: 255, 255, 255; 9 | } 10 | 11 | @media (prefers-color-scheme: dark) { 12 | :root { 13 | --foreground-rgb: 255, 255, 255; 14 | --background-start-rgb: 0, 0, 0; 15 | --background-end-rgb: 0, 0, 0; 16 | } 17 | } 18 | 19 | body { 20 | color: rgb(var(--foreground-rgb)); 21 | background: linear-gradient( 22 | to bottom, 23 | transparent, 24 | rgb(var(--background-end-rgb)) 25 | ) 26 | rgb(var(--background-start-rgb)); 27 | } 28 | -------------------------------------------------------------------------------- /src/app/layout.tsx: -------------------------------------------------------------------------------- 1 | import { Footer, Navbar } from '@/components' 2 | import './globals.css' 3 | import type { Metadata } from 'next' 4 | import { Inter } from 'next/font/google' 5 | 6 | const inter = Inter({ subsets: ['latin'] }) 7 | 8 | export const metadata: Metadata = { 9 | title: 'Starter Next App', 10 | description: 'Generated by create next app', 11 | } 12 | 13 | export default function RootLayout({ 14 | children, 15 | }: { 16 | children: React.ReactNode 17 | }) { 18 | return ( 19 | 20 | 21 | 22 | {children} 23 |