public/Next.js static file serving exposes any file placed inside the root public/ directory at your site's base URL /. Use public/ for favicons, downloadable PDFs, robots.txt, brand logos, and verification files.
Files inside public/ are served directly without Webpack or Turbopack bundling. A file at public/logo.svg becomes reachable at https://yoursite.com/logo.svg right away.
public/ Folders to URLsOrganize static assets cleanly in subfolders under public/, while keeping URL references rooted at /.
my-next-app/
├── app/
│ └── page.tsx
└── public/
├── favicon.ico
├── robots.txt
├── docs/
│ └── privacy-policy.pdf
└── images/
└── brand-mark.svg
public/favicon.ico maps to /favicon.icopublic/docs/privacy-policy.pdf maps to /docs/privacy-policy.pdfpublic/images/brand-mark.svg maps to /images/brand-mark.svgStart asset paths with a leading slash / and leave out the word public from every URL string.
// app/components/SiteHeader.tsx
import Image from 'next/image';
export default function SiteHeader() {
return (
<header className="flex items-center justify-between p-4 border-b">
<Image
src="/images/brand-mark.svg"
alt="Workspace Logo"
width={36}
height={36}
/>
<a
href="/docs/privacy-policy.pdf"
target="_blank"
rel="noopener noreferrer"
className="text-sm text-blue-600 underline"
>
Privacy Policy (PDF)
</a>
</header>
);
}
public/Next.js also supports special files directly inside app/, such as app/icon.png, app/robots.ts, and app/sitemap.ts. Use app/ conventions for dynamic sitemaps or generated icons, and keep fixed files like downloadable PDFs in public/.
/public/logo.svg in src or href: Next.js strips public from the public URL, so /public/logo.svg returns a 404 error.public/about.html and app/about/page.tsx causes routing conflicts.public/: Every file inside public/ can be downloaded openly by anyone on the internet.public/ after npm run build served automatically?No, Next.js indexes public/ at build time; dynamically uploaded user files should live in object storage like S3 or Cloudflare R2.
public/?By default Next.js avoids aggressive immutable caching on public/ files because their filenames do not contain content hashes, though CDNs can cache them with custom headers.
public/ or assets/?Photos used in JSX can live in public/ or be imported directly from a src/assets/ folder so <Image> reads dimensions automatically.
Sign in to track your learning journey, earn industry-recognized certificates, and join our elite developer community.
Quick Access With