logo
eng-flag

Next.js Cheatsheet

Table of Contents

  1. Project Setup
  2. Routing
  3. Pages
  4. API Routes
  5. Data Fetching
  6. Styling
  7. Image Optimization
  8. Font Optimization
  9. Static File Serving
  10. Environment Variables
  11. TypeScript Support
  12. Deployment
  13. Performance Optimization
  14. Internationalization
  15. Authentication
  16. Testing

Project Setup

Create a new Next.js project

npx create-next-app@latest my-next-app
cd my-next-app

Run the development server

npm run dev

Build for production

npm run build

Start the production server

npm start

Routing

Basic routing

// pages/index.js
export default function Home() {
  return <h1>Home Page</h1>
}

// pages/about.js
export default function About() {
  return <h1>About Page</h1>
}

Dynamic routes

// pages/posts/[id].js
import { useRouter } from 'next/router'

export default function Post() {
  const router = useRouter()
  const { id } = router.query

  return <p>Post: {id}</p>
}

Catch-all routes

// pages/posts/[...slug].js
import { useRouter } from 'next/router'

export default function Post() {
  const router = useRouter()
  const { slug } = router.query

  return <p>Slug: {slug.join('/')}</p>
}
import Link from 'next/link'

export default function NavBar() {
  return (
    <nav>
      <Link href="/">Home</Link>
      <Link href="/about">About</Link>
    </nav>
  )
}

Programmatic navigation

import { useRouter } from 'next/router'

export default function Page() {
  const router = useRouter()

  return (
    <button onClick={() => router.push('/about')}>
      Go to About
    </button>
  )
}

Pages

Custom App

// pages/_app.js
import '../styles/globals.css'

function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />
}

export default MyApp

Custom Document

// pages/_document.js
import { Html, Head, Main, NextScript } from 'next/document'

export default function Document() {
  return (
    <Html lang="en">
      <Head />
      <body>
        <Main />
        <NextScript />
      </body>
    </Html>
  )
}

Error Page

// pages/404.js
export default function Custom404() {
  return <h1>404 - Page Not Found</h1>
}

// pages/500.js
export default function Custom500() {
  return <h1>500 - Server-side error occurred</h1>
}

API Routes

Basic API route

// pages/api/hello.js
export default function handler(req, res) {
  res.status(200).json({ message: 'Hello from Next.js!' })
}

Dynamic API route

// pages/api/posts/[id].js
export default function handler(req, res) {
  const { id } = req.query
  res.status(200).json({ id, message: `Post ${id}` })
}

Data Fetching

getServerSideProps

export async function getServerSideProps(context) {
  const res = await fetch(`https://api.example.com/data`)
  const data = await res.json()

  return {
    props: { data },
  }
}

export default function Page({ data }) {
  return <div>{data.title}</div>
}

getStaticProps

export async function getStaticProps() {
  const res = await fetch(`https://api.example.com/data`)
  const data = await res.json()

  return {
    props: { data },
    revalidate: 60, // Optional: revalidate every 60 seconds
  }
}

export default function Page({ data }) {
  return <div>{data.title}</div>
}

getStaticPaths

export async function getStaticPaths() {
  const res = await fetch('https://api.example.com/posts')
  const posts = await res.json()

  const paths = posts.map((post) => ({
    params: { id: post.id.toString() },
  }))

  return { paths, fallback: false }
}

export async function getStaticProps({ params }) {
  const res = await fetch(`https://api.example.com/posts/${params.id}`)
  const post = await res.json()

  return { props: { post } }
}

export default function Post({ post }) {
  return <div>{post.title}</div>
}

Styling

CSS Modules

// styles/Home.module.css
.container {
  padding: 0 2rem;
}

// pages/index.js
import styles from '../styles/Home.module.css'

export default function Home() {
  return <div className={styles.container}>Hello World</div>
}

Sass Support

npm install sass
// styles/globals.scss
$font-stack: Helvetica, sans-serif;
$primary-color: #333;

body {
  font: 100% $font-stack;
  color: $primary-color;
}

// pages/_app.js
import '../styles/globals.scss'

CSS-in-JS (Styled JSX)

export default function Button() {
  return (
    <div>
      <button>Click me</button>
      <style jsx>{`
        button {
          background-color: blue;
          color: white;
          padding: 10px 20px;
        }
      `}</style>
    </div>
  )
}

Image Optimization

Next.js Image Component

import Image from 'next/image'

export default function Avatar() {
  return (
    <Image
      src="/images/profile.jpg"
      alt="Profile picture"
      width={500}
      height={500}
    />
  )
}

Font Optimization

Next.js Font Module

import { Inter } from 'next/font/google'

const inter = Inter({ subsets: ['latin'] })

export default function MyApp({ Component, pageProps }) {
  return (
    <main className={inter.className}>
      <Component {...pageProps} />
    </main>
  )
}

Static File Serving

Serving static files

Place files in the public directory:

public/
  images/
    profile.jpg

Access in your code:

<img src="/images/profile.jpg" alt="Profile picture" />

Environment Variables

Using environment variables

// .env.local
DB_HOST=localhost
DB_USER=myuser
DB_PASS=mypassword
// pages/api/db.js
export default function handler(req, res) {
  res.status(200).json({ 
    host: process.env.DB_HOST,
    user: process.env.DB_USER
  })
}

TypeScript Support

Adding TypeScript

npm install --save-dev typescript @types/react @types/node

Rename files to use .ts or .tsx extension.

Deployment

npm install -g vercel
vercel

Static HTML Export

next build
next export

Performance Optimization

Automatic Prefetching

Next.js automatically prefetches the JavaScript code for the linked pages in the background.

Dynamic Imports

import dynamic from 'next/dynamic'

const DynamicComponent = dynamic(() => import('../components/hello'))

export default function Home() {
  return (
    <div>
      <DynamicComponent />
    </div>
  )
}

Internationalization

Routing

// next.config.js
module.exports = {
  i18n: {
    locales: ['en', 'fr', 'de'],
    defaultLocale: 'en',
  },
}

Translation

import { useRouter } from 'next/router'

const dict = {
  en: { greeting: 'Hello' },
  fr: { greeting: 'Bonjour' },
  de: { greeting: 'Hallo' },
}

export default function Page() {
  const router = useRouter()
  const { locale } = router
  return <h1>{dict[locale].greeting}</h1>
}

Authentication

Using NextAuth.js

npm install next-auth
// pages/api/auth/[...nextauth].js
import NextAuth from 'next-auth'
import Providers from 'next-auth/providers'

export default NextAuth({
  providers: [
    Providers.GitHub({
      clientId: process.env.GITHUB_ID,
      clientSecret: process.env.GITHUB_SECRET
    }),
  ],
})

Testing

Jest and React Testing Library

npm install --save-dev jest @testing-library/react @testing-library/jest-dom
// __tests__/index.test.js
import { render, screen } from '@testing-library/react'
import Home from '../pages/index'

describe('Home', () => {
  it('renders a heading', () => {
    render(<Home />)

    const heading = screen.getByRole('heading', {
      name: /welcome to next.js!/i,
    })

    expect(heading).toBeInTheDocument()
  })
})

Run tests:

npm test

2024 © All rights reserved - buraxta.com