Dynamic Import & Asset Management
next/dynamic lets you load a component only when needed. That shrinks the first JavaScript bundle for heavy charts, editors, or maps.
Dynamic import with next/dynamic
next/dynamic lets you load a component only when needed. That shrinks the first JavaScript bundle for heavy charts, editors, or maps.
Dynamic imports are useful for Client Components that are large or only shown after a click.
Real-life example: Dynamic import is packing a suitcase for a day trip — leave the winter coat at home and pick it up only if the weather turns cold.
import dynamic from "next/dynamic";
const HeavyChart = dynamic(() => import("@/components/HeavyChart"), {
loading: () => <p>Loading chart...</p>,
ssr: false,
});
export default function AnalyticsPage() {
return (
<main>
<h1>Course analytics</h1>
<HeavyChart />
</main>
);
}Lazy loading components
You can also use React.lazy in Client Components, but next/dynamic is the Next.js-friendly helper with loading UI and ssr options.
Real-life example: Lazy loading is a streaming playlist — the next song downloads when you need it, not the entire album at once when you open the app.
"use client";
import { useState } from "react";
import dynamic from "next/dynamic";
const MarkdownEditor = dynamic(() => import("@/components/MarkdownEditor"), {
loading: () => <p>Opening editor...</p>,
});
export function NotesPanel() {
const [open, setOpen] = useState(false);
return (
<div>
<button onClick={() => setOpen(true)}>Write notes</button>
{open ? <MarkdownEditor /> : null}
</div>
);
}Static files from public/
Anything in public/ is served from the site root. public/avatar.png is available at /avatar.png. Do not import these through the JS bundler unless you need hashed imports.
Use public/ for favicons, downloadable PDFs, robots.txt, and simple static images referenced by string path.
Real-life example: public/ is the open notice board in a school hallway — anyone who knows the path can read the poster without asking the teacher (bundler) to fetch it.
- Reference as src="/file.png" — leading slash matters
- Nested folders work: public/icons/home.svg → /icons/home.svg
- Files are copied as-is — no automatic image optimization unless you use next/image
export default function Resources() {
return (
<ul>
<li>
<a href="/docs/syllabus.pdf" download>
Download syllabus
</a>
</li>
<li>
<img src="/icons/book.svg" alt="" width={24} height={24} />
Course icon from public/
</li>
</ul>
);
}