default.js in Next.js — Graceful Fallbacks for Parallel and Dynamic Routes

In Next.js, the default.js file provides a fallback for Parallel Routes when the active state of a slot cannot be recovered after a full-page load. This article explains how to use default.js, access dynamic route parameters, handle catch-all segments, and generate static paths with generateStaticParams.

default.jsParallel RoutesDynamic SegmentsgenerateStaticParams

~2 min read • Updated Oct 29, 2025

1. What Is default.js?


In Parallel Routes, Next.js preserves the active state of each slot during soft navigation. But after a hard navigation (full-page reload), it cannot recover the active state. In such cases, a default.js file is rendered for unmatched slots.


Example:

When navigating to /settings, the @team slot renders the settings page, but @analytics has no matching route. If default.js is missing, Next.js throws an error.


Manual 404 fallback:

// app/@team/default.js
import { notFound } from 'next/navigation'

export default function Default() {
  notFound()
}

2. Accessing Dynamic Params in default.js


The params prop is a promise. Use async/await or use() to access values.

// app/[artist]/@sidebar/default.js
export default async function Default({ params }) {
  const { artist } = await params
}

3. Dynamic Segments in Next.js


Create dynamic segments by wrapping folder names in square brackets:

// app/blog/[slug]/page.tsx
export default async function Page({ params }) {
  const { slug } = await params
  return <div>My Post: {slug}</div>
}

4. In Client Components


Use use() or useParams() to access dynamic params:

'use client'
import { use } from 'react'

export default function BlogPostPage({ params }) {
  const { slug } = use(params)
  return <p>{slug}</p>
}

5. Catch-all vs Optional Catch-all Segments


  • Catch-all: [...slug] → matches only when params exist
  • Optional Catch-all: [[...slug]] → also matches routes without params

Example:

// app/shop/[[...slug]]/page.js
// /shop → { slug: undefined }
// /shop/clothes → { slug: ['clothes'] }
// /shop/clothes/tops → { slug: ['clothes', 'tops'] }

6. Typing Params in TypeScript


Use PageProps or RouteContext for precise typing. You can also validate values at runtime:

function assertValidLocale(value: string): asserts value is Locale {
  if (!isValidLocale(value)) notFound()
}

7. Using generateStaticParams


Generate static paths at build time:

export async function generateStaticParams() {
  const posts = await fetch('https://.../posts').then(res => res.json())
  return posts.map(post => ({ slug: post.slug }))
}

Fetch calls inside this function are automatically deduplicated to speed up builds.


Conclusion


The default.js file plays a key role in handling Parallel Routes and fallback behavior in Next.js. Combined with dynamic segments, catch-all routing, and static generation, it helps build fast, resilient, and flexible applications.


Written & researched by Dr. Shahin Siami