favicon, icon, apple-icon file conventions overview
The favicon, icon, and apple-icon file conventions allow you to set icons for your application. They are useful for adding app icons that appear in places like web browser tabs, phone home screens, and search engine results.
Two ways to set app icons
App icons can be set in two ways: using image files (.ico, .jpg, .png), or using code to generate an icon (.js, .ts, .tsx).
favicon image file convention
The favicon file convention supports only .ico file type and can only be located in app/. Add a favicon.ico image file to the root /app route segment. Next.js will automatically add the appropriate tag <link rel="icon" href="/favicon.ico" sizes="any" /> to your app's <head> element.
icon image file convention
The icon file convention supports .ico, .jpg, .jpeg, .png, and .svg file types and can be located in app/**/*. Add an icon.(ico|jpg|jpeg|png|svg) image file. Next.js will automatically add the appropriate tag <link rel="icon" href="/icon?<generated>" type="image/<generated>" sizes="<generated>" /> to your app's <head> element.
apple-icon image file convention
The apple-icon file convention supports .jpg, .jpeg, and .png file types and can be located in app/**/*. Add an apple-icon.(jpg|jpeg|png) image file. Next.js will automatically add the appropriate tag <link rel="apple-touch-icon" href="/apple-icon?<generated>" type="image/<generated>" sizes="<generated>" /> to your app's <head> element.
Multiple icons with numbered suffixes
You can set multiple icons by adding a number suffix to the file name. For example, icon1.png, icon2.png, etc. Numbered files will sort lexically.
Favicon location restriction
Favicons can only be set in the root /app segment. If you need more granularity, you can use the icon convention instead.
Generated icon attributes based on file metadata
The appropriate <link> tags and attributes such as rel, href, type, and sizes are determined by the icon type and metadata of the evaluated file. For example, a 32 by 32px .png file will have type="image/png" and sizes="32x32" attributes. sizes="any" is added to icons when the extension is .svg or the image size of the file is not determined.
Generate icons using code with ImageResponse
Generate an app icon by creating an icon or apple-icon route that default exports a function. The easiest way to generate an icon is to use the ImageResponse API from next/og. File conventions: icon supports .js, .ts, .tsx; apple-icon supports .js, .ts, .tsx.
Generated icon code example with ImageResponse
```tsx filename="app/icon.tsx"
import { ImageResponse } from 'next/og'
// Image metadata
export const size = {
width: 32,
height: 32,
}
export const contentType = 'image/png'
// Image generation
export default function Icon() {
return new ImageResponse(
(
// ImageResponse JSX element
<div
style={{
fontSize: 24,
background: 'black',
width: '100%',
height: '100%',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
color: 'white',
}}
>
A
</div>
),
// ImageResponse options
{
// For convenience, we can re-use the exported icons size metadata
// config to also set the ImageResponse's width and height.
...size,
}
)
}
```
Generated icon static optimization
By default, generated icons are statically optimized (generated at build time and cached) unless they use Request-time APIs or uncached data.
Multiple icons from generateImageMetadata
You can generate multiple icons in the same file using generateImageMetadata.
Cannot generate favicon with code
You cannot generate a favicon icon using code. Use the icon convention or a favicon.ico file instead.
App icons caching behavior
App icons are special Route Handlers that are cached by default unless they use a Request-time API or dynamic config option.
Icon function params prop (optional)
The default export function receives an optional params prop: a promise that resolves to an object containing the dynamic route parameters object from the root segment down to the segment icon or apple-icon is colocated in. When using generateImageMetadata, the function will also receive an id prop that is a promise resolving to the id value from one of the items returned by generateImageMetadata.
Icon function params examples
Route app/shop/icon.js with URL /shop has params undefined. Route app/shop/[slug]/icon.js with URL /shop/1 has params Promise<{ slug: '1' }>. Route app/shop/[tag]/[item]/icon.js with URL /shop/1/2 has params Promise<{ tag: '1', item: '2' }>.
Icon function params type
```tsx
export default async function Icon({
params,
}: {
params: Promise<{ slug: string }>
}) {
const { slug } = await params
// ...
}
```
Icon function return type
The default export function should return a Blob | ArrayBuffer | TypedArray | DataView | ReadableStream | Response. ImageResponse satisfies this return type.
Icon size config export
You can optionally configure the icon's metadata by exporting a size variable from the icon or apple-icon route. Type: { width: number; height: number }. Example: export const size = { width: 32, height: 32 } produces <link rel="icon" sizes="32x32" />.
Icon contentType config export
You can optionally configure the icon's metadata by exporting a contentType variable from the icon or apple-icon route. Type: string (image MIME type). Example: export const contentType = 'image/png' produces <link rel="icon" type="image/png" />.
Icon and apple-icon route segment config
icon and apple-icon are specialized Route Handlers that can use the same route segment configuration options as Pages and Layouts.
params promise change in v16.0.0
In version 16.0.0, params is now a promise that resolves to an object.
favicon, icon, and apple-icon introduced in v13.3.0
The favicon, icon, and apple-icon file conventions were introduced in version 13.3.0.
not-found.js file convention
The not-found.js file is used to render UI when the notFound function is called within a route segment. Next.js returns a 200 HTTP status code for streamed responses and 404 for non-streamed responses. In the component hierarchy, not-found.js renders between loading.js and page.js, wrapped by the Suspense boundary from loading.js and the error boundary from error.js in the same segment.
global-not-found.js file convention
The global-not-found.js file (experimental, added in v15.4.0) defines a 404 page for the entire application when a requested URL doesn't match any route. Unlike not-found.js which works at the route level, global-not-found.js bypasses normal rendering and directly returns the page. It must return a full HTML document including html and body tags. It skips rendering layouts, so you must import global styles, fonts, and theme dependencies directly in this file.
global-not-found.js requires configuration
To enable global-not-found.js, add the globalNotFound flag to next.config.ts under experimental: { globalNotFound: true }. Then create the file at app/global-not-found.js in the root of the app directory.
global-not-found.js use cases
global-not-found.js is useful in two scenarios: when your app has multiple root layouts (e.g. app/(admin)/layout.tsx and app/(shop)/layout.tsx) so there's no single layout to compose a global 404 from, or when your root layout uses top-level dynamic segments (e.g. app/[country]/layout.tsx), making it harder to compose a consistent 404 page.
not-found.js does not accept props
Components exported from not-found.js or global-not-found.js do not accept any props.
Root not-found.js handles unmatched URLs
The root app/not-found.js and app/global-not-found.js files handle any unmatched URLs for the whole application. Users visiting a URL not handled by the app will be shown the exported UI from these files.
not-found.js as async Server Component for data fetching
not-found.js is by default a Server Component and can be marked as async to fetch and display data. Example: export default async function NotFound() { const headersList = await headers(); const domain = headersList.get('host'); const data = await getSiteData(domain); return (...); }
global-not-found.js theme and styling requirements
global-not-found.js bypasses the app's normal rendering and layout, so you must import global styles, fonts, and theme dependencies directly in the file. The OS color scheme is the only default signal the UI sees, so you must apply your theme (class or attribute) inside this file. A smaller version of global styles and simpler font family could improve performance.
not-found.js color scheme and theming
The default not-found UI follows the operating system's color scheme via prefers-color-scheme and does not read app-level themes (class or data-theme attribute on html). Because it renders inside the root layout, the quickest way to match an explicit theme is to add a higher-specificity rule pair in global stylesheet, scoped to the theme selector (e.g., html[data-theme='light'] body and html[data-theme='dark'] body). For full control over markup, provide a custom not-found.js.
global-not-found.js example with metadata
Example global-not-found.tsx file:
```tsx
import type { Metadata } from 'next'
export const metadata: Metadata = {
title: 'Not Found',
description: 'The page you are looking for does not exist.',
}
export default function GlobalNotFound() {
return (
<html lang="en">
<body>
<div>
<h1>Not Found</h1>
<p>The page you are looking for does not exist.</p>
</div>
</body>
</html>
)
}
```
global-not-found.js example with styles and fonts
Example global-not-found.tsx file:
```tsx
import './globals.css'
import { Inter } from 'next/font/google'
import type { Metadata } from 'next'
const inter = Inter({ subsets: ['latin'] })
export const metadata: Metadata = {
title: '404 - Page Not Found',
description: 'The page you are looking for does not exist.',
}
export default function GlobalNotFound() {
return (
<html lang="en" className={inter.className}>
<body>
<h1>404 - Page Not Found</h1>
<p>This page does not exist.</p>
</body>
</html>
)
}
```
template.js file convention
A template file is a special file in the app directory that wraps a layout or page. It is defined by exporting a default React component from a template.js file. The component should accept a children prop.
template vs layout key difference
Unlike layouts that persist across routes and maintain state, templates are given a unique key, meaning children Client Components reset their state on navigation.
template use cases
Templates are useful when you need to resynchronize useEffect on navigation, reset the state of child Client Components on navigation (for example, an input field), or change default framework behavior such as having Suspense boundaries show a fallback on every navigation instead of only on first load.
template component hierarchy position
In the component hierarchy, template.js renders between layout.js and error.js. It wraps error.js, loading.js, not-found.js, and page.js, but does not wrap the layout.js in the same segment.
template rendering order in output
Templates are rendered between a layout and its children. The simplified output shows: <Layout>{/* template is given a unique key */}<Template key={routeParam}>{children}</Template></Layout>
template props
Templates accept a required children prop of type React.ReactNode.
templates are Server Components by default
By default, templates are Server Components.
template remounting on navigation
Templates receive a unique key for their own segment level. They remount when that segment (including its dynamic params) changes. Navigations within deeper segments do not remount higher-level templates. Search params do not trigger remounts.
template state reset behavior
Any Client Component inside the template will reset its state on navigation. Effects like useEffect will re-synchronize as the component remounts. DOM elements inside the template are fully recreated.
template remounting example across segments
When navigating from / to /about, the root template key changes and it remounts. When navigating from /about to /blog, the root template key changes and remounts, while a blog-level template mounts. When navigating from /blog to /blog/first-post, the root template key does not change (same first segment), but the blog-level template key changes and remounts. When navigating to /blog/second-post, the root template key again does not change, but the blog-level template key changes and remounts again.
template.tsx example implementation
export default function Template({ children }: { children: React.ReactNode }) {
return <div>{children}</div>
}
template.js example implementation
export default function Template({ children }) {
return <div>{children}</div>
}
template introduced in version
The template file convention was introduced in Next.js v13.0.0.
Server Components support progressive enhancement by default
Server Components support progressive enhancement by default, meaning forms that call Server Actions will be submitted even if JavaScript hasn't loaded yet or is disabled.