-
Node version 20.1.0
- This project is setup to use asdf. This allows installing a specific version for the project. To install nodejs with asdf, see https://github.com/asdf-vm/asdf-nodejs
- If using nvm, run
nvm useto set a compatible version based on the project .nvmrc
-
Yarn (for package management)
- This project is setup to use asdf. This allows installing a specific version for the project. To install yarn with asdf, see https://github.com/twuni/asdf-yarn
- Or install globally via npm:
npm i -g yarn
-
Docker (Desktop)
-
PostgreSQL https://www.postgresql.org/
-
Create an env file
Create a file called
.envin project's root directory. Copy the contents of .env.template. See more on Environment Variables.cp .env.template .env
-
Install dependencies by using yarn
yarn
-
Initialize the DB
yarn prisma:migrate:dev
This will run the Prisma migrations found in ./prisma/migrations and seed the database from ./prisma/seedData/index.ts.
-
Set up Husky
Run
yarn prepare -
Run the development server.
-
Read about starting the app Dockerized.
-
Read about starting the app Non-Dockerized.
The app is started with the
devscript frompackage.jsonyarn dev
Open http://localhost:3000 with your browser to see the result.
Log in with
test@email.comandtestPassw0rd! -
A simple way to get PostgreSQL running locally is to use Docker. Here is a simple Dockerized PostgreSQL server with pgAdmin:
If you are running on a Linux operating system the default connection to the docker container host.docker.internal will not work. To connect to the local dockerized PostgreSQL DB, ensure there is a .env file (.env.template can be used as a reference.) In the .env file, ensure the DB_URL variable has host.docker.internal replaced with 172.17.0.1.
DB_URL="postgresql://postgres:docker@172.17.0.1:5432/my_db_dev?schema=public"Alternatively, the app may be set up to connect to the existing staging database or another database.
To connect to a different database (ie staging), the .env file must also be used with values similar to:
DB_URL="postgresql://{get_the_database_user}:{get_the_database_password}@{get_the_database_host}:{get_the_database_port}/{get_the_database_name}?schema=public"- setup testing:
npx playwright install - test:
yarn test
The development server must be running in order to execute playwright tests.
Unit tests written with Jest + @react-testing-library. Integration tests written in Playwright.
yarn test # Run all tests
yarn test:unit # Run unit tests
yarn test:e2e # Run integration tetsYou can start editing the page by modifying pages/index.js. The page auto-updates as you edit the file.
The pages/api directory is mapped to /api/*. Files in this directory are treated as API routes instead of React pages.
All the environment variables used by the app have defaults. To set the environment variables, simply run the following bash script from the root of the project folder:
bash ./set_env_variables.shThe default environment variables' values may be over-written by adding the value to a .env file in the root of the project folder. This file is not versioned in the repository.
The .env.template file is an example of what the .env could be like and may be used as a reference.
To reset the environment variables to the defaults (still using the values in the .env file), run the following bash script in the root of the project folder:
bash ./reset_env_variables.shThis project uses husky to test code before changes are committed. This means that linting, unit, and e2e tests are run locally before changes can be committed by default.
Husky pre-commit scripts can be skipped by using the --no-verify flag, or the -n alias of the same flag.
git commit --no-verify -m "<conventional commit message>"or
git commit -n -m "<conventional commit message>"Use the Conventional Commit format when writing commit messages. See the contributing guide for more information.
NextJS can be used to build Static React Apps that are deployed on a static CDN like an AWS S3 Bucket, github pages, or any static hosting provider. It can also be used as a full stack framework with a Node Express backend that serves server side rendered (SSR) react pages, that includes an API. This server implementation is optional. Static Generating is recommended for most client side only React apps.
Nextjs can be removed entirely by removing the contents of the ./src folder, next.config.js and next-env.d.ts. Then place whatever React implementation you prefer.
- Next.js: Tried and tested React full-stack react framework.
- Typescript: Configured and ready to go. With path aliases
- Prisma: The best Node ORM. Type safe front end to back.
- PostgreSQL: Ready to go database running in a docker container for easy development.
- Docker: docker for the the db in development and set up to export the whole project for easy shipping.
- ReactQuery: API request management made super simple with hooks.
- Tailwind: Like bootstrap, but good. A flexible styling framework that only exports the styles you use.
- EsLint: linting policies configured to work with prettier and auto sort imports.
- Jest: unit tests configured with jest on front and backend.
- Playwright: Cross browser integration testing.
- Localization routing: Easily add multi-language support, using Next.js' i18n routing.
- Plop code generator: Keep your code dry and modular, while improving DX.
- React Final Form: High performance subscription-based form state management for React.
- Zod: Validate and parse form inputs while keeping all types consistent. TypeScript-first schema validation with static type inference.
- Husky: Prevent bad code from being pushed with pre-commit hooks already configured to lint and test before pushing local changes.
This project uses plop templates to generate consistent code that is flat and modular. Running yarn plop will allow you to generate a component (common, partial, or page), data model, or type.
Plop will generate the appropriate code template in the appropriate folder. In the case of components plop will generate a folder with a nested component tsx, unit tests, types, and index for easier imports. In the case of pages, plop will generate the appropriate component in the /pages folder and /components/pages.
yarn plopYou can also skip any part of the interactive menu by calling plop with the proper arguments.
yarn plop component common <commonComponent>Learn more about using plop for generating cleaner code
To learn more about Next.js, take a look at the following resources:
- Next.js Documentation - learn about Next.js features and API.
- Learn Next.js - an interactive Next.js tutorial.
You can check out the Next.js GitHub repository - your feedback and contributions are welcome!
A static react app generated at build time and hosted as client side only. All static content is pre-rendered on the page.
- See static generation
- Remove
/pages/api - Build app with
yarn build:static - See Next unsupported static features
A fullstack Nextjs app requires the app to be hosted in on most VMs that support Node.js. This server can be used to server-side generate pages, host api logic, and optimize page loading. This is optional.
- See server side rendering
- See api routes
- See next/server
This project uses ReactQuery for 99% of the state management. All api queries should be wrapped in hook with the relative model, with a reference to react query.
Hooks for redux is used for client side only state management. Currently this is only be used by the Multi-Step Form and may be removed in the future.
app
├── __tests__
│ ├── __mocks__ // mock functions
│ ├── integration // end to end integration tests
│ └── unit // global unit tests
├── .github
│ └── workflows // workflow yaml files for github actions
├── .vscode // recommended extensions and settings for vscode
├── .husky
│ └── pre-commit // actions to be executed before allowing a code push
├── .github
│ └── workflows // workflow yaml files for github actions
├── plop_templates // templates for plop code generation
├── prisma
│ ├── migrations // prisma generated database migrations
│ ├── seedData // contains fake data in json format for seeding development database
│ ├── schema.prisma // prisma schema file
│ └── seed.ts // script executed to seed prisma development database
├── src
│ ├── components
│ │ ├── common // simple components with no state management
│ │ │ // the building blocks for partials and pages
│ │ | └── <Component> // Component folder
│ │ | ├── <Component>.spec.ts // unit test for component
│ │ | ├── <Component>.tsx // component JSX markup
│ │ | ├── <Component>.types.tsx // types used by the component
│ │ | └── index.ts // generated index file to easily import
│ │ ├── partials // complex components and model specific components (e.g. TodoForm vs Form)
│ │ │ // composed of other partials (sparingly) and common components
│ │ | └── <Component> // shares the same component folder structure as common
│ │ └── pages // contains jsx mark up for pages.
│ │ │ // composed of partials and common components
│ │ └── <Component> // shares the same component folder structure as common
│ ├── models
│ │ └── <Model>
│ │ ├── includes
│ │ │ └── index.ts // contains json objects to be used for prisma includes
│ │ ├── mutation
│ │ │ └── <action><Model>[By<Field>].ts // create | update | delete actions for model optionally specified field
│ │ ├── query
│ │ │ └── get<Model>[By<Field>].ts // read actions for model optionally specified field
│ │ └── <Model>.types.ts // model specific type references for prisma and zod validation
│ ├── pages // components in this folder are converted to page routes
│ │ ├── api // used for server routes if using NextJS fullstack.
│ │ │ // folders and nested files are converted into api routs via Nextjs
│ │ ├── _app.tsx // warps all other pages (similar to create-react-app app.tsx)
│ │ ├── _document.tsx // using by Nextjs when generating static pages
│ │ └── /**/*.tsx // all other folders and nested files generate app page routes
│ │ // actual markup should live in components/pages/<CorrespondingPageComponent>
│ ├── public // static files (images, icons, fonts)
│ ├── store // state management setup (hooks-for-redux)
│ ├── styles // global project styles
│ ├── types // all non-component, non-model specific types
│ └── utils // shared utility functions
│ ├── api // api specific utils
│ ├── client // client side specific utils
│ └── requests // client side logic for api url requests as promises
│
├── client.config.js // client in this case refers to the organization in which the app is being built for
│ // contains template information for quickly changing the project
├── .babelrc // babel config (for inlining css with Nextjs)
├── .dockerignore // which files docker ignores
├── .env.template // template env folder used for development !DO NOT PUT API KEYS HERE!
├── .eslintrc.js // eslint config
├── .gitignore // which files git ignores
├── .nvmrc // contains recommended node version
├── .prettierignore // which files should not be formatted
├── .prettierrc.js // code formatting rules
├── docker-compose.yml // docker compose to build db image (and production container if applicable)
├── Dockerfile // docker file to build production db and webapp images
├── jest.config.js // unit testing config
├── jest.setup.js // extends unit testing library
├── next-env.d.ts // Nextjs typescript setup
├── next.config.js // Nextjs config
├── package.json // project dependencies and versioning
├── playwright.config.ts// playwright config
├── plopfile.js // code template generator config file
├── postcss.config.js // post css processing config used for tailwind css
├── tsconfig.json // TS config and project absolute path config
├── tailwind.config.js // tailwind config
└── yarn.lock // generated yarn.lock file