Skip to content

aurorascharff/rsc-workshop-starter

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

92 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

React Server Components and React 19 in the Next.js App Router

This is a Next.js project bootstrapped with create-next-app.

Requirements

  • Installed Node.js
  • Installed Visual Studio Code

Usage

First, install the dependencies:

npm install

Then, run the development server:

npm run dev

Open http://localhost:3000 with your browser to see the result.

You can start editing the page by modifying app/page.tsx. The page auto-updates as you edit the file.

This project uses next/font to automatically optimize and load Inter, a custom Google Font.

Prisma Setup

Initialize the local sqllite db with:

npm run prisma.push

Seed prisma/seed.ts for initial data:

npm run prisma.seed

To view your data in the database, you can run:

npm run prisma.studio

Development Info

Development Tools

The project uses ESLint for linting and Prettier for code formatting. The configuration for these tools is located in .eslintrc.js and .prettierrc.js. The project is configured to run code formatting and linting on save in Visual Studio Code. Verify that code formatting and linting is executed on save as configured. Opening the .code-workspace file will ensure the correct extentions are set.

Naming Conventions

  • Pascal case for components
  • Kebab case for folders
  • Camel case for other files

Folder Structure

  • public - contains the static assets of the application
  • src - contains the source code of the application
  • src/app - contains the pages of the application using file based routing.
  • src/components - contains shared components used across the application. The same goes for the other shared folder like providers, hooks, utils, etc.
  • For each route, a local _components-folder can be used to store components that are only used in that route. Same goes for _hooks, _utils, etc.
  • src/data - contains server-side data fetching and mutations.

Every page folder should contain everything it needs to work. And every component or function should live at the nearest shared space in the hierarchy.

Routing

The project uses Next.js filesystem-based routing. To give a brief overview:

  • Folders below the app/-directory will be routes in the application.
  • For each folders inside src/app that is meant to be a route, there should be a page.tsx and alternatively layout.tsx for the route.
  • When using brackets [] in the name of a folder, the folder will be a dynamic route. The name of the folder will be the name of the parameter in the route.
  • There are additional tools, such as ignoring folders from routing by prefixing with _, and creating groups by wrapping with ().
  • Each route can also have a error.tsx file for handling application errors, and a not-found.tsx page for handling 404 errors with notFound().

Please refer to the Next.js App Router documentation for more information.

Note on Type-Safe Routing

In the Next.js App Router, routes, route params and search params are not typed by default. Therefore, next-safe-navigation is used for type-safe navigation. All routes are defined in src/validations/routeSchema.ts and can be used by calling routes.<routeName>.

In client components, parsing params is done with the hooks useSafeParams and useSafeSearchParams. For server components, the pageProps are passed down as an unknown object and validated with routes.<routeName>.$parseParams and routes.<routeName>.$parseSearchParams.

Note on React 19

The Next.js App Router uses React 19 Server Components, and by default all components are server components unless opted into client-side rendering with "use client". In addition, the project uses other React 19 features such as Server Functions, useFormStatus(), useOptimistic(), useActionState(), and async transitions with useTransition(). Please read the React docs on these features to understand how to use them. Read more about the use of Server Functions under Data Fetching and Mutation.

Note on the React Compiler

The project uses the React Compiler to optimize the application. The React Compiler is a new feature in React that optimizes the application by skipping rerenders and expensive functions calls, and removes the need for much manual momoization. The compiler is enabled in the next.config.ts file. It's currently in Beta, and everything it working well. Pay attention to it's behavior, and try to follow the eslint rules for it defined by eslint-plugin-react-compiler. Refer to the React Compiler documentation for more information.

Styling

The project uses Tailwind CSS for styling. Tailwind CSS is a utility-first CSS framework that allows you to rapidly build custom designs without leaving your HTML. The theme is configured in tailwind.config.js. Default styles are applied in /app/globals.css.

Use the cn util when merging conditional classes with other classes. Excess styling is applied in the components using Tailwind CSS utility classes. Tailwind also controls the responsive design of the application with a mobile-first approach. Refer to the Tailwind CSS documentation for more information.

Data Fetching and Mutation

The project uses Prisma for data fetching. Mutations are done using React Server Functions, skipping the Next.js 12 /api convention. Files are stores inside the src/data folder, where src/data/services are server-side data queries and src/data/actions are mutations. Take extra consideration when creating hidden endpoints with "use server" to avoid exposing sensitive data.

For more information, refer to the React Server Functions and Next.js Server Actions and Mutations documentation.

When using a form with an action, the loading state is included in the SubmitButton-component, and the form is disabled while the action is pending. For other cases, a loading state can be passed to to submit button or other components to handle the loading state.

Unit, Component and Integration Testing

The project uses Vitest for unit and component testing. Vitest is configured in vite.config.js, and set up in setupTests.ts. Test files are located in the same folder as their corresponding source files, and are named with the .test.tsx extension.

Note: RTL currently supports a workaround for async or suspended components by using Suspense. Use the helper function suspenseRender, located in /testUtils.tsx. When testing async or suspended components, use await findByTestId rather than getByTestId and equivalent functions. Error messages concerning uncached promises and async/await not being supported can be ignored.

Run unit and component tests with:

npm run test.unit

End-to-End Testing

The project uses Playwright for end-to-end testing. Playwright is configured in playwright.config.ts. Test files are located in the e2e folder, and are named with the .test.ts extension.

  • Run e2e tests with:
npm run test.e2e
  • Run e2e tests in debug mode with:
npm run test.e2e.debug
  • Generate e2e test code with:
npm run test.e2e.codegen

You might have to run npx playwright install before running the tests, as prompted by the terminal.

Deployment

The app can be built for production using the npm run build command. The built files will be generated in the .next folder.

The easiest way to deploy your Next.js app is to use the Vercel Platform from the creators of Next.js.

Check out our Next.js deployment documentation for more details.

Note that you cannot use the local SQLite database in production. You will need to configure a production database in the .env file and update the Prisma schema accordingly. Learn more about it in the docs.

Releases

No releases published

Packages

No packages published