javascript 43 lines · 7 steps

Archiving with router.refresh in Next.js

A client component archives a project, then refreshes server data without a full page reload.

Explained by highlit
1'use client';
2 
3import { useRouter } from 'next/navigation';
4import Link from 'next/link';
5import { useState, useTransition } from 'react';
6 
7export default function ProjectRow({ project }) {
8 const router = useRouter();
9 const [isPending, startTransition] = useTransition();
10 const [archiving, setArchiving] = useState(false);
11 
12 async function archive() {
13 setArchiving(true);
14 try {
15 const res = await fetch(`/api/projects/${project.id}/archive`, {
16 method: 'POST',
17 });
18 if (!res.ok) throw new Error('Failed to archive project');
19 
20 startTransition(() => {
21 router.refresh();
22 });
23 } finally {
24 setArchiving(false);
25 }
26 }
27 
28 return (
29 <li className="project-row">
30 <Link
31 href={`/projects/${project.id}`}
32 prefetch={false}
33 onMouseEnter={() => router.prefetch(`/projects/${project.id}`)}
34 >
35 {project.name}
36 </Link>
37 
38 <button onClick={archive} disabled={archiving || isPending}>
39 {archiving ? 'Archiving\u2026' : 'Archive'}
40 </button>
41 </li>
42 );
43}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1router.refresh re-fetches server components in place, so a mutation's effects appear without a full navigation.
  2. 2Wrapping the refresh in startTransition keeps the UI responsive and exposes an isPending flag for disabling controls.
  3. 3Deferring prefetch to onMouseEnter avoids eager network work while still making navigation feel instant on intent.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Archiving with router.refresh in Next.js — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code