A comprehensive guide for NextJS versions 13, 14, and 15
Key Points
This cheat sheet covers creating a NextJS app with features like App Router, Turbopack, File-based Metadata API, Dynamic Open Graph Images, and more for versions 13, 14, and 15.
- Turbopack, introduced in version 15, speeds up development with faster builds using next dev --turbopack.
- File-based Metadata API and Dynamic OG Images, available since version 13.3, enhance SEO and social sharing with easy metadata management.
Creating Pages
NextJS uses the App Router for a file-based routing system, where pages are created in the app directory. For example, create a file like app/about/page.js for an /about route. This supports layouts, nested routes, and dynamic segments like [id].
app/ βββ page.js # Home route (/) βββ about/ β βββ page.js # About route (/about) βββ blog/ βββ [slug]/ βββ page.js # Dynamic blog posts (/blog/post-1)
App Router
The App Router, introduced in NextJS 13, is the default routing system located in the app directory. It supports Server Components, layouts, and improved data fetching. To use, create files in app with .js, .jsx, or .tsx extensions.
Turbopack
Turbopack, stable in NextJS 15, is a fast Rust-based bundler for development. Enable it with next dev --turbopack. It's only for development (next dev), not production builds.
next dev --turbopack
File-Based Metadata API
Available since NextJS 13.3, define metadata like favicons and OG images using files. Place static files like favicon.ico in the root, or use dynamic files like opengraph-image.js for generated content.
app/ βββ favicon.ico βββ opengraph-image.js βββ layout.js
Dynamic Open Graph Images
Part of the Metadata API since 13.3, create dynamic OG images with ImageResponse. Import from next/server for 13.3-13.x, or next/og for 14+.
import { ImageResponse } from 'next/og' export const runtime = 'edge' export default function og() { return new ImageResponse( <div style={{ fontSize: 128, background: 'white', width: '100%', height: '100%', display: 'flex', alignItems: 'center', justifyContent: 'center', }} > Hello World </div> ) }
Static Export for App Router
Enable static exports by setting output: 'export' in next.config.js. This generates HTML, CSS, and JavaScript files for deployment, suitable for static hosting.
// next.config.js module.exports = { output: 'export' }
Parallel Routes and Interception
Parallel Routes allow multiple pages to render simultaneously using slots like @modal. Interception routes handle navigation, defined with intercepting in the App Router.
app/ βββ @modal/ β βββ login/ β βββ page.tsx βββ layout.tsx
Style Your NextJS App
NextJS supports multiple styling solutions including CSS Modules, Tailwind CSS, and styled-components. Import CSS files directly or use next/font for optimized fonts.
// CSS Modules import styles from './styles.module.css' // Google Fonts import { Inter } from 'next/font/google' const inter = Inter({ subsets: ['latin'] })
Optimize Images & Fonts
NextJS optimizes images with the next/image component, supporting formats like WebP. Use next/font for Google Fonts with automatic optimization.
import Image from 'next/image' export default function Hero() { return ( <Image src="/hero.jpg" alt="Hero image" width={1200} height={600} priority /> ) }
Custom 404 Pages
Create a not-found.js file in the app directory for custom 404 pages. NextJS will render it for not-found routes, enhancing user experience.
// app/not-found.tsx export default function NotFound() { return <h1>404 - Page Not Found</h1> }
Data Fetching
NextJS provides multiple ways to fetch data. You can use Server Components, fetch API, or SWR for client-side data fetching.
// Server Component async function getData() { const res = await fetch('https://api.example.com') return res.json() } // Client Component with SWR const { data } = useSWR('/api/data')
Linting Your Code
NextJS includes ESLint by default. Run next lint to check for errors. Configure in .eslintrc.json for custom rules, ensuring code quality.
{ "extends": "next/core-web-vitals", "rules": { // your custom rules } }
TypeScript Support
NextJS supports TypeScript out-of-the-box. Create .ts or .tsx files, e.g., app/page.tsx. It provides type checking and better IDE support.
// app/page.tsx export default function Page({ params }: { params: { id: string } }) { return <h1>Post {params.id}</h1> }
Using Scripts
Add scripts in pages/_document.js or use the Script component from next/script for third-party scripts.
import Script from 'next/script' export default function Layout() { return ( <> <Script src="https://example.com/script.js" /> {/* Your content */} </> ) }
API Routes
Create API routes in app/api directory using Route Handlers. These support various HTTP methods and can be used for backend functionality.
// app/api/hello/route.ts export async function GET() { return Response.json({ message: 'Hello' }) } export async function POST(request: Request) { const body = await request.json() return Response.json({ received: body }) }
π Indie Kit - NextJS 15 Boilerplate
Start your next project with a production-ready NextJS 15 boilerplate. Get all the features you need to build your SaaS, AI, or B2B application and get it to market faster.
- Complete NextJS 15 boilerplate with App Router
- SEO optimization & Blog with MDX
- Email integration (SES/Mailgun/Resend)
- Payment processing (Stripe/Lemon Squeezy)
- Database setup (Planetscale/NeonDB)
- Background Jobs & Queue management
- Authentication (Google Auth & Magic Link)
- UI Components & Design System
- Quota Management Hooks
- Super Admin Dashboard
- Waitlist Module with analytics
- Working Contact Form
- Pro tips for better coding workflow
- Plan Management & Subscriptions
- Access to Discord Community
- Lifetime Updates & Support
Middlewares
Define middlewares in middleware.js at the root. Use for authentication, redirects, or modifying responses.
// middleware.ts import { NextResponse } from 'next/server' import type { NextRequest } from 'next/server' export function middleware(request: NextRequest) { return NextResponse.redirect(new URL('/home', request.url)) }
Authentication
Implement authentication using NextAuth.js or custom solutions. Configure in app/api/auth/[...nextauth]/route.js for OAuth, email, etc.
// app/api/auth/[...nextauth]/route.ts import NextAuth from 'next-auth' import GithubProvider from 'next-auth/providers/github' const handler = NextAuth({ providers: [ GithubProvider({ clientId: process.env.GITHUB_ID, clientSecret: process.env.GITHUB_SECRET, }), ], })
Testing
Test with Jest, React Testing Library, or Playwright. Set up in package.json with scripts like 'test': 'jest'.
// __tests__/Home.test.tsx import { render, screen } from '@testing-library/react' import Home from '@/app/page' describe('Home', () => { it('renders a heading', () => { render(<Home />) expect(screen.getByRole('heading')).toBeInTheDocument() }) })