NextjsStatic Assets & the public Folder

Static Assets & the public Folder

Not every asset needs optimization — sometimes you just need a file served exactly as it is, at a predictable URL. That's what the public folder at the root of a Next.js project is for. Anything placed inside it is served as-is, starting from the root of your site.

Folder structure and resulting URLs

Text
public/
  favicon.ico          →  /favicon.ico
  robots.txt           →  /robots.txt
  manifest.json         →  /manifest.json
  images/
    logo.svg            →  /images/logo.svg
Common use cases
  • favicon.ico and other browser icons expected at a fixed, well-known path

  • robots.txt and sitemap.xml for search engine crawlers

  • manifest.json for Progressive Web App metadata

  • Files that need a stable, predictable URL referenced from outside your app (e.g. a PDF linked from an email)

  • Assets used by third-party scripts or verification files (domain ownership tokens, ads.txt)

Referencing a public asset

TSX
export default function Page() {
  return (
    <div>
      {/* No import needed — reference the path directly */}
      <a href="/downloads/brochure.pdf">Download brochure</a>
      <img src="/images/logo.svg" alt="Company logo" />
    </div>
  )
}
Note
Files in public are copied verbatim into the build output and served with no processing whatsoever — no compression beyond your hosting platform's defaults, no resizing, no format conversion. This is the opposite of what next/image does with <Image>: an image referenced with a plain <img src="/images/logo.svg" /> tag from public gets none of the responsive sizing, lazy loading, or format optimization that wrapping it in <Image> would provide. Use public for files that genuinely need to stay untouched at a fixed path, and reach for next/image for anything you want optimized.
Naming and caching considerations
Because files in public are served at the root of your domain, their names effectively become part of your app's public URL surface — avoid naming a file the same as a route you plan to add (a file at public/about.html would conflict with a route at app/about/page.tsx). Also keep in mind that, unlike hashed build assets, files in public don't get an automatic cache-busting filename when you change them, so aggressive browser or CDN caching can serve a stale version unless you version the filename yourself or configure cache headers.
  • Anything in public/ is served as-is from the root URL, with no build-time processing.

  • It's the right place for favicons, robots.txt, manifest.json, and files that need a fixed, stable URL.

  • Unlike next/image, files here get no automatic optimization — use next/image when you want that.

  • Filenames in public/ can collide with route paths, so choose them carefully.