ERP/.shared/ui-ux-pro-max/data/stacks/nextjs.csv
2026-01-03 19:18:40 +08:00

12 KiB

1NoCategoryGuidelineDescriptionDoDon'tCode GoodCode BadSeverityDocs URL
21RoutingUse App Router for new projectsApp Router is the recommended approach in Next.js 14+app/ directory with page.tsxpages/ for new projectsapp/dashboard/page.tsxpages/dashboard.tsxMediumhttps://nextjs.org/docs/app
32RoutingUse file-based routingCreate routes by adding files in app directorypage.tsx for routes layout.tsx for layoutsManual route configurationapp/blog/[slug]/page.tsxCustom router setupMediumhttps://nextjs.org/docs/app/building-your-application/routing
43RoutingColocate related filesKeep components styles tests with their routesComponent files alongside page.tsxSeparate components folderapp/dashboard/_components/components/dashboard/Low
54RoutingUse route groups for organizationGroup routes without affecting URLParentheses for route groupsNested folders affecting URL(marketing)/about/page.tsxmarketing/about/page.tsxLowhttps://nextjs.org/docs/app/building-your-application/routing/route-groups
65RoutingHandle loading statesUse loading.tsx for route loading UIloading.tsx alongside page.tsxManual loading state managementapp/dashboard/loading.tsxuseState for loading in pageMediumhttps://nextjs.org/docs/app/building-your-application/routing/loading-ui-and-streaming
76RoutingHandle errors with error.tsxCatch errors at route levelerror.tsx with reset functiontry/catch in every componentapp/dashboard/error.tsxtry/catch in page componentHighhttps://nextjs.org/docs/app/building-your-application/routing/error-handling
87RenderingUse Server Components by defaultServer Components reduce client JS bundleKeep components server by defaultAdd 'use client' unnecessarilyexport default function Page()('use client') for static contentHighhttps://nextjs.org/docs/app/building-your-application/rendering/server-components
98RenderingMark Client Components explicitly'use client' for interactive componentsAdd 'use client' only when neededServer Component with hooks/events('use client') for onClick useStateNo directive with useStateHighhttps://nextjs.org/docs/app/building-your-application/rendering/client-components
109RenderingPush Client Components downKeep Client Components as leaf nodesClient wrapper for interactive parts onlyMark page as Client Component<InteractiveButton/> in Server Page('use client') on page.tsxHigh
1110RenderingUse streaming for better UXStream content with Suspense boundariesSuspense for slow data fetchesWait for all data before render<Suspense><SlowComponent/></Suspense>await allData then renderMediumhttps://nextjs.org/docs/app/building-your-application/routing/loading-ui-and-streaming
1211RenderingChoose correct rendering strategySSG for static SSR for dynamic ISR for semi-staticgenerateStaticParams for known pathsSSR for static contentexport const revalidate = 3600fetch without cache configMedium
1312DataFetchingFetch data in Server ComponentsFetch directly in async Server Componentsasync function Page() { const data = await fetch() }useEffect for initial dataconst data = await fetch(url)useEffect(() => fetch(url))Highhttps://nextjs.org/docs/app/building-your-application/data-fetching
1413DataFetchingConfigure caching explicitly (Next.js 15+)Next.js 15 changed defaults to uncached for fetchExplicitly set cache: 'force-cache' for static dataAssume default is cached (it's not in Next.js 15)fetch(url { cache: 'force-cache' })fetch(url) // Uncached in v15Highhttps://nextjs.org/docs/app/building-your-application/upgrading/version-15
1514DataFetchingDeduplicate fetch requestsReact and Next.js dedupe same requestsSame fetch call in multiple componentsManual request deduplicationMultiple components fetch same URLCustom cache layerLow
1615DataFetchingUse Server Actions for mutationsServer Actions for form submissionsaction={serverAction} in formsAPI route for every mutation<form action={createPost}><form onSubmit={callApiRoute}>Mediumhttps://nextjs.org/docs/app/building-your-application/data-fetching/server-actions-and-mutations
1716DataFetchingRevalidate data appropriatelyUse revalidatePath/revalidateTag after mutationsRevalidate after Server Action'use client' with manual refetchrevalidatePath('/posts')router.refresh() everywhereMediumhttps://nextjs.org/docs/app/building-your-application/caching#revalidating
1817ImagesUse next/image for optimizationAutomatic image optimization and lazy loading<Image> component for all images<img> tags directly<Image src={} alt={} width={} height={}><img src={}/>Highhttps://nextjs.org/docs/app/building-your-application/optimizing/images
1918ImagesProvide width and heightPrevent layout shift with dimensionswidth and height props or fillMissing dimensions<Image width={400} height={300}/><Image src={url}/>High
2019ImagesUse fill for responsive imagesFill container with object-fitfill prop with relative parentFixed dimensions for responsive<Image fill className="object-cover"/><Image width={window.width}/>Medium
2120ImagesConfigure remote image domainsWhitelist external image sourcesremotePatterns in next.config.jsAllow all domainsremotePatterns: [{ hostname: 'cdn.example.com' }]domains: ['*']Highhttps://nextjs.org/docs/app/api-reference/components/image#remotepatterns
2221ImagesUse priority for LCP imagesMark above-fold images as prioritypriority prop on hero imagesAll images with priority<Image priority src={hero}/><Image priority/> on every imageMedium
2322FontsUse next/font for fontsSelf-hosted fonts with zero layout shiftnext/font/google or next/font/localExternal font linksimport { Inter } from 'next/font/google'<link href="fonts.googleapis.com"/>Mediumhttps://nextjs.org/docs/app/building-your-application/optimizing/fonts
2423FontsApply font to layoutSet font in root layout for consistencyclassName on body in layout.tsxFont in individual pages<body className={inter.className}>Each page imports fontLow
2524FontsUse variable fontsVariable fonts reduce bundle sizeSingle variable font fileMultiple font weights as filesInter({ subsets: ['latin'] })Inter_400 Inter_500 Inter_700Low
2625MetadataUse generateMetadata for dynamicGenerate metadata based on paramsexport async function generateMetadata()Hardcoded metadata everywheregenerateMetadata({ params })export const metadata = {}Mediumhttps://nextjs.org/docs/app/building-your-application/optimizing/metadata
2726MetadataInclude OpenGraph imagesAdd OG images for social sharingopengraph-image.tsx or og propertyMissing social preview imagesopengraph: { images: ['/og.png'] }No OG configurationMedium
2827MetadataUse metadata APIExport metadata object for static metadataexport const metadata = {}Manual head tagsexport const metadata = { title: 'Page' }<head><title>Page</title></head>Medium
2928APIUse Route Handlers for APIsapp/api routes for API endpointsapp/api/users/route.tspages/api for new projectsexport async function GET(request)export default function handlerMediumhttps://nextjs.org/docs/app/building-your-application/routing/route-handlers
3029APIReturn proper Response objectsUse NextResponse for API responsesNextResponse.json() for JSONPlain objects or res.json()return NextResponse.json({ data })return { data }Medium
3130APIHandle HTTP methods explicitlyExport named functions for methodsExport GET POST PUT DELETESingle handler for all methodsexport async function POST()switch(req.method)Low
3231APIValidate request bodyValidate input before processingZod or similar for validationTrust client inputconst body = schema.parse(await req.json())const body = await req.json()High
3332MiddlewareUse middleware for authProtect routes with middleware.tsmiddleware.ts at rootAuth check in every pageexport function middleware(request)if (!session) redirect in pageMediumhttps://nextjs.org/docs/app/building-your-application/routing/middleware
3433MiddlewareMatch specific pathsConfigure middleware matcherconfig.matcher for specific routesRun middleware on all routesmatcher: ['/dashboard/:path*']No matcher configMedium
3534MiddlewareKeep middleware edge-compatibleMiddleware runs on Edge runtimeEdge-compatible code onlyNode.js APIs in middlewareEdge-compatible auth checkfs.readFile in middlewareHigh
3635EnvironmentUse NEXT_PUBLIC prefixClient-accessible env vars need prefixNEXT_PUBLIC_ for client varsServer vars exposed to clientNEXT_PUBLIC_API_URLAPI_SECRET in client codeHighhttps://nextjs.org/docs/app/building-your-application/configuring/environment-variables
3736EnvironmentValidate env varsCheck required env vars existValidate on startupUndefined env at runtimeif (!process.env.DATABASE_URL) throwprocess.env.DATABASE_URL (might be undefined)High
3837EnvironmentUse .env.local for secretsLocal env file for development secrets.env.local gitignoredSecrets in .env committed.env.local with secrets.env with DATABASE_PASSWORDHigh
3938PerformanceAnalyze bundle sizeUse @next/bundle-analyzerBundle analyzer in devShip large bundles blindlyANALYZE=true npm run buildNo bundle analysisMediumhttps://nextjs.org/docs/app/building-your-application/optimizing/bundle-analyzer
4039PerformanceUse dynamic importsCode split with next/dynamicdynamic() for heavy componentsImport everything staticallyconst Chart = dynamic(() => import('./Chart'))import Chart from './Chart'Mediumhttps://nextjs.org/docs/app/building-your-application/optimizing/lazy-loading
4140PerformanceAvoid layout shiftsReserve space for dynamic contentSkeleton loaders aspect ratiosContent popping in<Skeleton className="h-48"/>No placeholder for async contentHigh
4241PerformanceUse Partial PrerenderingCombine static and dynamic in one routeStatic shell with Suspense holesFull dynamic or static pagesStatic header + dynamic contentEntire page SSRLowhttps://nextjs.org/docs/app/building-your-application/rendering/partial-prerendering
4342LinkUse next/link for navigationClient-side navigation with prefetching<Link href=""> for internal links<a> for internal navigation<Link href="/about">About</Link><a href="/about">About</a>Highhttps://nextjs.org/docs/app/api-reference/components/link
4443LinkPrefetch strategicallyControl prefetching behaviorprefetch={false} for low-priorityPrefetch all links<Link prefetch={false}>Default prefetch on every linkLow
4544LinkUse scroll option appropriatelyControl scroll behavior on navigationscroll={false} for tabs paginationAlways scroll to top<Link scroll={false}>Manual scroll managementLow
4645ConfigUse next.config.js correctlyConfigure Next.js behaviorProper config optionsDeprecated or wrong optionsimages: { remotePatterns: [] }images: { domains: [] }Mediumhttps://nextjs.org/docs/app/api-reference/next-config-js
4746ConfigEnable strict modeCatch potential issues earlyreactStrictMode: trueStrict mode disabledreactStrictMode: truereactStrictMode: falseMedium
4847ConfigConfigure redirects and rewritesUse config for URL managementredirects() rewrites() in configManual redirect handlingredirects: async () => [...]res.redirect in pagesMediumhttps://nextjs.org/docs/app/api-reference/next-config-js/redirects
4948DeploymentUse Vercel for easiest deployVercel optimized for Next.jsDeploy to VercelSelf-host without knowledgevercel deployComplex Docker setup for simple appLowhttps://nextjs.org/docs/app/building-your-application/deploying
5049DeploymentConfigure output for self-hostingSet output option for deployment targetoutput: 'standalone' for DockerDefault output for containersoutput: 'standalone'No output config for DockerMediumhttps://nextjs.org/docs/app/building-your-application/deploying#self-hosting
5150SecuritySanitize user inputNever trust user inputEscape sanitize validate all inputDirect interpolation of user dataDOMPurify.sanitize(userInput)dangerouslySetInnerHTML={{ __html: userInput }}High
5251SecurityUse CSP headersContent Security Policy for XSS protectionConfigure CSP in next.config.jsNo security headersheaders() with CSPNo CSP configurationHighhttps://nextjs.org/docs/app/building-your-application/configuring/content-security-policy
5352SecurityValidate Server Action inputServer Actions are public endpointsValidate and authorize in Server ActionTrust Server Action inputAuth check + validation in actionDirect database call without checkHigh