Next.js 15 fullstack (App Router + Server Actions) · leksjon

Tag-basert ugyldiggjøring for detaljert tømming av cache

Knytt cache-tagger til fetch-kall, og ugyldiggjør nøyaktig dataene som påvirkes etter mutasjoner.

Leksjon 3 av 413 trinn

Tag-basert ugyldiggjøring for detaljert tømming av cache er en gratis leksjon i Next.js 15 fullstack (App Router + Server Actions) på CoddyKit. Dette er leksjon 3 av 4. Du kan lese valgfritt 3 leksjoner fra denne læringsstien gratis i sin helhet – deretter låser CoddyKit PRO opp alle leksjoner, samt praktisk øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i Next.js 15 fullstack (App Router + Server Actions), og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i Next.js 15 fullstack (App Router + Server Actions) inneholder totalt 4 leksjoner.

Hvorfor ugyldiggjøring basert på tagger

I Next.js 15 lagrer Data Cache resultater fra fetch på tvers av forespørsler og utrullinger. Utfordringen er å ugyldiggjøre akkurat de riktige oppføringene etter en endring.

  • Tidsbasert revalidering (revalidate: 60) er grovkornet og styres av klokken.
  • Stibasert revalidering (revalidatePath) tømmer hele rutesegmenter.
  • Taggbasert revalidering lar Dem merke individuelle fetch-kall og ugyldiggjøre bare disse, uansett hvilken side som gjenga dem.

Tagger gir Dem detaljert og målrettet tømming av hurtigbufferen: Oppdater ett produkt og ugyldiggjør bare fetch-kallene som leser dette produktet.

Knytte en tagg til en fetch

De knytter tagger til fetch gjennom alternativet next.tags på den utvidede fetch-funksjonen. Hver tagg er en vanlig tekststreng De velger selv.

Her er et fetch-kall for en produktliste merket med to tagger: en bred products-tagg og en spesifikk product-42-tagg.

  • Den brede taggen ugyldiggjør hele samlingen.
  • Den spesifikke taggen ugyldiggjør ett element.
async function getProduct(id: string) {
  const res = await fetch(`https://api.shop.com/products/${id}`, {
    next: { tags: ['products', `product-${id}`] },
  });
  if (!res.ok) throw new Error('Failed to load product');
  return res.json();
}

Ugyldiggjøre med revalidateTag

Etter en endring kaller De revalidateTag(tag) fra next/cache. Alle hurtigbufrede fetch-kall som har denne taggen, markeres som utdaterte. Ved neste forespørsel hentes oppdaterte data på nytt.

Dette kjøres i en Server Action eller en Route Handler — kontekster som bare finnes på serveren, der endringer utføres.

  • revalidateTag returnerer ikke et løfte som De venter på for å hente data på nytt; den markerer bare oppføringene som utdaterte.
  • Flere tagger? Kall den én gang per tagg.
'use server';
import { revalidateTag } from 'next/cache';

export async function updateProduct(id: string, data: FormData) {
  await fetch(`https://api.shop.com/products/${id}`, {
    method: 'PATCH',
    body: JSON.stringify({ name: data.get('name') }),
  });
  // Bust only this product's cached reads
  revalidateTag(`product-${id}`);
}

Brede og smale tagger

Design et lite tagghierarki slik at De kan velge riktig rekkevidde:

  • products — ugyldiggjør hele katalogen (for eksempel etter en masseimport).
  • product-42 — ugyldiggjør ett enkelt element (for eksempel etter en redigering).
  • product-42-reviews — ugyldiggjør en relatert del uten å påvirke selve produktet.

Tommelfingerregel: Merk hvert fetch-kall med både en samlingstagg og en entitetstagg. Da kan endringer bruke den minste taggen som dekker endringen.

Tagge lesinger på tvers av sider

En tagg er global for Data Cache og er ikke knyttet til en rute. Hvis både hjemmesiden og detaljsiden henter product-42 med samme tagg, ugyldiggjør ett revalidateTag('product-42')-kall begge.

Dette er den viktigste fordelen sammenlignet med revalidatePath: De trenger ikke vite hvilke sider som brukte dataene.

// app/page.tsx (home) and app/products/[id]/page.tsx both call this
export async function getProductSummary(id: string) {
  const res = await fetch(`https://api.shop.com/products/${id}`, {
    next: { tags: [`product-${id}`] },
  });
  return res.json();
}

unstable_cache for data som ikke kommer fra fetch

Ikke alle data kommer fra fetch — direkte spørringer mot databasen (Prisma, Drizzle) går utenom Data Cache. Pakk dem inn i unstable_cache for å få støtte for tagger.

Det tredje argumentet tar imot tags og revalidate. Det samme revalidateTag-kallet ugyldiggjør også disse oppføringene.

import { unstable_cache } from 'next/cache';
import { db } from '@/lib/db';

export const getCachedUser = unstable_cache(
  async (id: string) => db.user.findUnique({ where: { id } }),
  ['user-by-id'],
  { tags: ['users'], revalidate: 3600 },
);

Dynamiske tagger i unstable_cache

Hurtigbufferens nøkkeldeler (det andre argumentet) må være tilstrekkelig statiske til å identifisere funksjonen, men De ønsker ofte en tagg per entitet. Bygg taggen fra argumentet og send den inn i alternativene.

Returner funksjonen slik at hvert kall får riktig entitetstagg, noe som muliggjør presisjonen i revalidateTag('user-7').

import { unstable_cache } from 'next/cache';
import { db } from '@/lib/db';

export function getCachedUser(id: string) {
  return unstable_cache(
    async () => db.user.findUnique({ where: { id } }),
    ['user', id],
    { tags: [`user-${id}`, 'users'] },
  )();
}

Bygge tagnavn på en trygg måte

Inkonsistente taggstrenger mislykkes i stillhet — en tagg som ikke samsvarer, ugyldiggjør ingenting. Sentraliser konstruksjonen av tagger i rene hjelpefunksjoner slik at lesing og skriving alltid bruker de samme taggene.

Dette er frittstående, idiomatisk TypeScript: Hjelpefunksjonene produserer nøyaktig de samme strengene som brukes både i next.tags og revalidateTag.

const tags = {
  products: () => 'products',
  product: (id: string) => `product-${id}`,
  productReviews: (id: string) => `product-${id}-reviews`,
};

console.log(tags.products());
console.log(tags.product('42'));
console.log(tags.productReviews('42'));

Ugyldiggjøre flere tagger atomisk

Én endring påvirker ofte flere hurtigbufrede deler. Etter at et produkt er oppdatert, kan De måtte ugyldiggjøre elementet, samlingslisten og søkeindeksen.

Kall revalidateTag for hver av dem. Alle trer i kraft samtidig før svaret fra handlingen returneres til klienten.

  • Rekkefølgen spiller ingen rolle — alle markeres som utdaterte.
  • Hold mengden minimal for å unngå unødvendig henting andre steder.
'use server';
import { revalidateTag } from 'next/cache';

export async function publishProduct(id: string) {
  await fetch(`https://api.shop.com/products/${id}/publish`, { method: 'POST' });
  revalidateTag(`product-${id}`);
  revalidateTag('products');
  revalidateTag('search-index');
}

Tagg eller sti: Velg

Både revalidateTag og revalidatePath finnes for ulike oppgaver:

  • Bruk tagger når de samme dataene vises på mange ruter, eller når De bare vil ugyldiggjøre data og ikke de hurtigbufrede antakelsene for en gjengitt rute i et layout.
  • Bruk sti når hele resultatet for en rute er endret, og De ikke bruker tagger der.

De kan kombineres: En Server Action kan kalle begge. Foretrekk tagger for data og stier for strukturelle endringer på hele siden.

Fra ende til ende i en Server Action

Her er hele flyten: Et skjema sender data til en Server Action, handlingen endrer backend-systemet og ugyldiggjør deretter de presise taggene. Neste gang en side som leser disse taggene, gjengis, får den automatisk oppdaterte data.

Merk at vi ugyldiggjør både entitetstaggen og samlingstaggen, fordi redigeringen også endrer listen.

'use server';
import { revalidateTag } from 'next/cache';
import { redirect } from 'next/navigation';

export async function editProduct(id: string, formData: FormData) {
  await fetch(`https://api.shop.com/products/${id}`, {
    method: 'PATCH',
    body: JSON.stringify({ name: formData.get('name') }),
    headers: { 'Content-Type': 'application/json' },
  });
  revalidateTag(`product-${id}`);
  revalidateTag('products');
  redirect(`/products/${id}`);
}

Kort kontroll

Et produktdetalj-fetch-kall er merket med ['products', 'product-42'] og vises også i listen på hjemmesiden (med samme tagg). De redigerer bare navnet på produkt 42. Hva er den mest presise måten å oppdatere begge visningene på uten å ugyldiggjøre andre produkter?

Oppsummering

De har lært detaljert, taggbasert tømming av hurtigbufferen i Next.js 15:

  • Knytt tagger til fetch via next: { tags: [...] }, og via alternativet tags i unstable_cache for data som ikke kommer fra fetch.
  • Bruk en samlingstagg sammen med en entitetstagg slik at endringer får minst mulig rekkevidde.
  • Kall revalidateTag(tag) i Server Actions eller Route Handlers — én gang per tagg, atomisk.
  • Tagger er globale: Ett kall oppdaterer dataene på alle ruter som leste dem, i motsetning til revalidatePath.
  • Sentraliser taggstrengene i hjelpefunksjoner slik at lesing og skriving aldri kommer i utakt.
Gratis å komme i gang

Lær deg TypeScript med en AI-veileder – gratis

Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.

Kurs
22
Leksjoner
88

Ofte stilte spørsmål

Er leksjonen «Tag-basert ugyldiggjøring for detaljert tømming av cache» gratis?

Ja – du kan lese valgfritt 3 av leksjonene i læringsstien Next.js 15 fullstack (App Router + Server Actions), inkludert «Tag-basert ugyldiggjøring for detaljert tømming av cache», gratis i sin helhet her på nettet. Deretter låser CoddyKit PRO opp alle leksjoner, samt interaktiv øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Kurset i Next.js 15 fullstack (App Router + Server Actions) inneholder totalt 4 leksjoner.

Hva lærer jeg i «Tag-basert ugyldiggjøring for detaljert tømming av cache»?

Knytt cache-tagger til fetch-kall, og ugyldiggjør nøyaktig dataene som påvirkes etter mutasjoner. Du øver på Next.js 15 fullstack (App Router + Server Actions) med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.

Trenger jeg erfaring for å begynne med Next.js 15 fullstack (App Router + Server Actions)?

Ingen tidligere erfaring er nødvendig. Next.js 15 fullstack (App Router + Server Actions) på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 3 av 4.

Hvor lang tid tar leksjonen «Tag-basert ugyldiggjøring for detaljert tømming av cache»?

De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.

Kan jeg skrive og kjøre kode i denne Next.js 15 fullstack (App Router + Server Actions)-leksjonen?

Ja. Alle Next.js 15 fullstack (App Router + Server Actions)-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.

Alle leksjonene i dette kurset

  1. De fire cachene: forespørsel, data, full rute og ruter
  2. Strategier for tidsbasert og behovsstyrt revalidering
  3. Tag-basert ugyldiggjøring for detaljert tømming av cache
  4. Velge bort caching: dynamisk gjengivelse og no-store
← Tilbake til Next.js 15 fullstack (App Router + Server Actions)