root ├── app, server only, include Server Side Render (SSR) pages and API route handlers ├── components, server/client, inclue reusable pure React Components ├── hooks, client only, inclue reusable logic work with states ├── models, server/client, represent domain data structure ├── db, server only │ ├── migrations, include database migrations │ └── seeds, define test data ├── public, client only, contains static assets ├── server,server only │ ├── middlewares, process before route handler and process returned response │ ├── repositories, operate with DB │ ├── services, process main logic │ └── route-handler-wrapper.ts, is Higher-Order Function (HOF) includes common process before or after route handler ├── services, client only, interact with remote services ├── store/context, client only, manage global states ├── types, server/client, include API contracts and common usage types ├── utils, include reusable helper functions ├── .env, server/client, include environment variables ├── .gitignore, ignore files won't be committed ├── middleware.ts, server only, is nextjs middleware entry, include middlewares from server/middlewares ├── next.config.ts, is nextjs project configuration ├── package.json, define project dependecies ├── README.md, show info about project └── tsconfig.json, typescript configuration
Environment Variable
Management
all variables are defined in .env file.
variable prefix with NEXT_PUBLIC_, server/client
variable prefix withoutNEXT_PUBLIC_,
server only
1 2 3 4 5 6 7
# .env
# expose for client and server NEXT_PUBLIC_CLIENT_VAR=test
# only expose for server DATABASE_URL="mysql://root:root@localhost:3306/kid-resource"
Route
nextjs use app router for routing, it follows
directory hierarchy, all route/controller handlers
define in app folder, it contains:
page.tsx, Page component with Server Side Render
(SSR)
defined in route.tsx and must export function with
http method name as handlers. recommend to use
NextRequest/NextResponse that extend
Request/Response.
Error Boundary in error.tsx file is
only used for client component.
define a fixed Error Response and return it when
expected error is raised.
use Error Boundary handle uncaught
exceptions
Mixture for
Server Component with Client Component
use React's use hook to stream data
with Promise from the server to client in Client
Component.
use streaming to break up the page's HTML into smaller chunks and
send those chunks from the server to the client.
wrap Client component with loading component
use loading.tsx file in route directory
wrap with Suspense by manual
1 2 3 4 5 6 7 8 9 10 11 12 13 14
// Server Component part importPostsfrom'@/app/ui/posts import { Suspense } from 'react' export default function Page() { // Don't await the data fetching function const posts = getPosts() return ( <Suspensefallback={<div>Loading...</div>}> <Postsposts={posts} /> </Suspense> ) }