new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Next.js App Router · all subjects

app-router/navigation

22 notes, read out of this brain and free to use. Each one was extracted from a source and is re-checked against its exam.

Routes rendered server-side by default in Next.js

In Next.js, Layouts and Pages are React Server Components by default. On initial and subsequent navigations, the Server Component Payload is generated on the server before being sent to the client.

Prerendering vs Dynamic Rendering

Prerendering happens at build time or during revalidation and the result is cached. Dynamic Rendering happens at request time in response to a client request.

Prefetching automatically enabled for Link component

Next.js automatically prefetches routes linked with the <Link> component when they enter the user's viewport or are hovered. Regular <a> tags do not trigger prefetching.

Prefetching behavior for static vs dynamic routes

For static routes, the full route is prefetched. For dynamic routes, prefetching is skipped, or the route is partially prefetched if loading.tsx is present. This avoids unnecessary server work for routes users may never visit.

Client-side transitions preserve shared layouts

Next.js uses client-side transitions with the <Link> component to avoid full page loads. Instead of reloading the page, it updates content dynamically by keeping any shared layouts and UI, and replacing the current page with the prefetched loading state or new page if available.

Link component handles scroll positioning during navigation

Next.js handles scrolling to the top of the page during client-side transitions. If content scrolls behind a sticky or fixed header after navigation, this can be fixed using CSS scroll-padding-top property.

Add loading.tsx to dynamic routes without it

When navigating to a dynamic route without loading.tsx, the client must wait for the server response before showing the result, giving users the impression that the app is not responding. Adding loading.tsx enables partial prefetching, triggers immediate navigation, and displays a loading UI while the route renders.

Use generateStaticParams to enable static generation for dynamic segments

If a dynamic segment could be prerendered but is missing generateStaticParams, the route falls back to dynamic rendering at request time. Add generateStaticParams to ensure the route is statically generated at build time.

generateStaticParams example

export async function generateStaticParams() { const posts = await fetch('https://.../posts').then((res) => res.json()) return posts.map((post) => ({ slug: post.slug, })) } export default async function Page({ params, }: { params: Promise<{ slug: string }> }) { const { slug } = await params // ... }

useLinkStatus hook for slow network feedback

On slow or unstable networks, prefetching may not finish before the user clicks a link. Use the useLinkStatus hook to show immediate feedback while the transition is in progress. The hook returns a pending boolean that can be used to display a loading indicator.

useLinkStatus example for loading indicator

'use client' import { useLinkStatus } from 'next/link' export default function LoadingIndicator() { const { pending } = useLinkStatus() return ( <span aria-hidden className={`link-hint ${pending ? 'is-pending' : ''}`} /> ) }

Debounce loading indicator with animation delay

To improve perceived performance on slow networks, add an initial animation delay (e.g. 100ms) to the loading indicator and start with invisible state (e.g. opacity: 0). This means the loading indicator will only show if navigation takes longer than the specified delay.

Disable prefetching with prefetch={false}

You can opt out of prefetching by setting the prefetch prop to false on the <Link> component. This is useful to avoid unnecessary resource usage when rendering large lists of links (e.g. infinite scroll table). Trade-offs: static routes are only fetched when clicked; dynamic routes need server rendering before client navigation.

Hover-only prefetching example

'use client' import Link from 'next/link' import { useState } from 'react' function HoverPrefetchLink({ href, children, }: { href: string children: React.ReactNode }) { const [active, setActive] = useState(false) return ( <Link href={href} prefetch={active ? null : false} onMouseEnter={() => setActive(true)} > {children} </Link> ) }

Link component is a Client Component requiring hydration

<Link> is a Client Component and must be hydrated before it can prefetch routes. On initial visit, large JavaScript bundles can delay hydration, preventing prefetching from starting right away. React mitigates this with Selective Hydration.

Improve hydration speed to enable faster prefetching

To speed up hydration and enable faster prefetching, use the @next/bundle-analyzer plugin to identify and reduce bundle size by removing large dependencies, and move logic from the client to the server where possible.

window.history.pushState for browser history

Next.js allows use of native window.history.pushState to add a new entry to the browser's history stack without reloading the page. The user can navigate back to the previous state. Calls integrate into the Next.js Router and sync with usePathname and useSearchParams hooks.

window.history.replaceState for browser history

Next.js allows use of native window.history.replaceState to replace the current entry on the browser's history stack without reloading the page. The user is not able to navigate back to the previous state. Calls integrate into the Next.js Router and sync with usePathname and useSearchParams hooks.

pushState example for sorting products

'use client' import { useSearchParams } from 'next/navigation' export default function SortProducts() { const searchParams = useSearchParams() function updateSorting(sortOrder: string) { const params = new URLSearchParams(searchParams.toString()) params.set('sort', sortOrder) window.history.pushState(null, '', `?${params.toString()}`) } return ( <> <button onClick={() => updateSorting('asc')}>Sort Ascending</button> <button onClick={() => updateSorting('desc')}>Sort Descending</button> </> ) }

replaceState example for locale switching

'use client' import { usePathname } from 'next/navigation' export function LocaleSwitcher() { const pathname = usePathname() function switchLocale(locale: string) { // e.g. '/en/about' or '/fr/contact' const newPath = `/${locale}${pathname}` window.history.replaceState(null, '', newPath) } return ( <> <button onClick={() => switchLocale('en')}>English</button> <button onClick={() => switchLocale('fr')}>French</button> </> ) }

Streaming for dynamic routes

Streaming allows the server to send parts of a dynamic route to the client as soon as they're ready, rather than waiting for the entire route to be rendered. For dynamic routes, shared layouts and loading skeletons can be partially prefetched ahead of time.

Client-side navigation behavior

Client-side navigation is a technique where page content updates dynamically without a full page reload. Next.js uses client-side navigation with the <Link> component, keeping shared layouts interactive and preserving browser state.

Give your agent this brain