`default.js` Explained: Fallbacks for Parallel Routes

default.js fills in a parallel route slot when Next.js cannot recover its active state after a full page load. Learn when it's required and what happens without one.

6 min read

The Next.js default.js file renders fallback content inside a parallel route slot when Next.js cannot tell which subpage was active there. This only comes up after a hard navigation, such as a full page reload, because a soft client-side navigation already keeps track of each slot's state on its own.

App.tsxApp.tsx
// app/dashboard/@analytics/default.tsx
export default function Default() {
  return null;
}

Returning null is the most common choice: it renders nothing for that slot until a route inside it is visited directly, while the rest of the dashboard renders normally around it.

Why a slot needs this at all

Consider a dashboard with a team slot and an analytics slot. Navigating client-side to a settings page updates only the team slot, leaving the analytics slot showing whatever it last displayed. Refreshing the page loses that memory entirely, since a fresh request has no client-side history to consult.

Next.js needs some content to put in the analytics slot for that fresh request, and the default file supplies it. Without one, the framework has no way to decide what belongs there on the very first render of a hard-loaded page.

What happens without one

A named slot with no default file and no matching route now throws an error during development and at build time, requiring you to add one before the route can render. This replaced the older behavior of silently falling back to a 404 for that slot. To restore the previous 404 fallback deliberately, call the notFound function from inside the file instead of returning null.

App.tsxApp.tsx
// app/dashboard/@analytics/default.tsx
import { notFound } from "next/navigation";
 
export default function Default() {
  notFound();
}

The implicit children slot behaves differently: skipping its default file still produces a 404 for the entire route on a hard navigation, not just an error demanding a fix, because children has no separate named slot folder to hold that file. Keeping that distinction straight avoids a confusing debugging session where one missing file throws loudly and another fails silently with a plain 404 page.

Reading params inside default.js

Like a page, default.tsx receives a params prop covering every dynamic segment from the root down to that slot, resolved as a promise.

App.tsxApp.tsx
// app/[artist]/@sidebar/default.tsx
export default async function Default({
  params,
}: {
  params: Promise<{ artist: string }>;
}) {
  const { artist } = await params;
  return <p>No sidebar view for {artist}</p>;
}

When to add one

Slot typeNeeds a default.js
Named slot, such as @analyticsYes, or the route errors
Implicit children slotYes, or the route 404s
A layout with no parallel route slotsNot applicable

Every project using parallel routes should add a default file to each slot from the start, rather than discovering the requirement from an error later. For the full slot convention this file supports, see parallel routes in Next.js. For the related file that resets state instead of filling a gap, see template.js vs layout.js.

Rune AI

Rune AI

Key Insights

  • default.js renders when a slot has no matching subpage after a hard navigation.
  • Soft, client-side navigation keeps a slot's last active state without needing this file.
  • A named slot without a default.js now throws a build or dev error instead of a silent 404.
  • Call notFound() inside default.js to restore the old 404 fallback behavior.
  • The implicit children slot still returns a 404 for the whole route if its default.js is missing.
RunePowered by Rune AI

Frequently Asked Questions

Does the children slot need its own default.js?

Yes. Because children is an implicit slot, it also needs a default.js when Next.js cannot recover its state on a hard navigation. Skipping it renders a 404 for the whole route.

Can default.js read the current dynamic segment?

Yes. It receives the same params prop as a page, resolved as a promise, covering every dynamic segment from the root down to that slot.

Does default.js run on the client or the server?

It runs as a Server Component by default, the same as a page or layout, unless you explicitly add the client directive to it.

Conclusion

default.js supplies fallback content for a parallel route slot when a hard navigation leaves Next.js unable to recover which subpage was active. Named slots now require one explicitly, while the implicit children slot still falls back to a 404 without it.