Next.js is a React framework that provides features such as SSR (Server-Side Rendering), SSG (Static Site Generation), and ISR (Incremental Static Regeneration) out of the box. These features help us to build high performance, SEO-friendly web applications. A comprehensive guide to using Next.js effectively, featuring a collection of handy code snippets and best practices for various features.
Dark Mode
- Update the global.css
- Define CSS variables for the background and foreground colors
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
:root {
--background: #ffffff;
--foreground: #000000;
}
.dark {
--background: #000000;
--foreground: #ffffff;
}
}
- Create theme-provider.tsx
import { ThemeProvider as NextThemesProvider } from "next-themes";
import { ThemeProviderProps } from "next-themes/dist/types";
import * as React from "react";
export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
return <NextThemesProvider {...props}>{children}</NextThemesProvider>;
}
- Update layout.tsx
- Wrap the application with the ThemeProvider component
import { ThemeProvider } from "@/components/theme-provider";
import { Inter } from "next/font/google";
const inter = Inter({ subsets: ["latin"] });
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en" suppressHydrationWarning>
<head />
<body className={inter.className}>
<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
{children}
</ThemeProvider>
</body>
</html>
);
}
- Create theme-switcher.tsx
- This component allows the user to switch between light and dark modes
import { useTheme } from "next-themes";
export const ThemeSwitcher = () => {
const { theme, setTheme } = useTheme();
return (
<div>
<button onClick={() => setTheme("light")}>Light Mode</button>
<button onClick={() => setTheme("dark")}>Dark Mode</button>
</div>
);
};
- Update tailwind.config.ts
import type { Config } from "tailwindcss";
const config: Config = {
content: [
"./src/pages/**/*.{js,ts,jsx,tsx,mdx}",
"./src/components/**/*.{js,ts,jsx,tsx,mdx}",
"./src/app/**/*.{js,ts,jsx,tsx,mdx}",
],
darkMode: ["class"],
theme: {
extend: {
colors: {
background: "var(--background)",
foreground: "var(--foreground)",
},
},
},
plugins: [],
};
getStaticProps
- A Next.js function that you can export from a page to fetch data at build time and pre-render the page with the fetched data
import type { GetStaticProps, InferGetStaticPropsType } from "next";
type Repo = {
name: string;
stargazers_count: number;
};
export const getStaticProps = (async (context) => {
const res = await fetch("https://api.github.com/repos/vercel/next.js");
const repo = await res.json();
return {
props: {
repo: repo,
},
revalidate: 10,
};
}) satisfies GetStaticProps<{
repo: Repo;
}>;
export default function Page({
repo,
}: InferGetStaticPropsType<typeof getStaticProps>) {
return repo.stargazers_count;
}
getStaticPaths
- A Next.js function that you can export from a page with dynamic routes
- It specifies a list of paths that Next.js should statically pre-render
export async function getStaticPaths() {
if (process.env.SKIP_BUILD_STATIC_GENERATION) {
return {
paths: [],
fallback: "blocking",
};
}
const res = await fetch("https://.../posts");
const posts = await res.json();
const paths = posts.map((post) => ({
params: { id: post.id },
}));
return { paths, fallback: false };
}
getServerSideProps
- A Next.js function that you can export from a page to fetch data at request time and pre-render the page with the fetched data
import type { InferGetServerSidePropsType, GetServerSideProps } from "next";
type Repo = {
name: string;
stargazers_count: number;
};
export const getServerSideProps = (async ({ req, res }) => {
res.setHeader(
"Cache-Control",
"public, s-maxage=10, stale-while-revalidate=59"
);
const res = await fetch("https://api.github.com/repos/vercel/next.js");
const repo = await res.json();
return {
props: {
repo: repo,
},
};
}) satisfies GetServerSideProps<{
repo: Repo;
}>;
export default function Page({
repo,
}: InferGetServerSidePropsType<typeof getServerSideProps>) {
return repo.stargazers_count;
}