Zum Hauptinhalt springen
Echtzeit-Radar & Feeds
Alle RSS Feeds ➔
👥 Community & Social
Windows Tipps & SecurityGrafikkarte vor Überhitzung schützen: So geht’s(25.09.2026 um 08:00 Uhr)
••••••••••
Windows Tipps & SecurityGrafikkarte vor Überhitzung schützen: So geht’s(25.09.2026 um 08:00 Uhr)
••••••••••
Intelligence View
⚡ tsecurity.de Intelligence

revalidateTag & updateTag In NextJs

We've been covering on-demand revalidation. Three functions allow you to revalidate on demand: revalidatePath revalidateTag updateTag In the previous chapter, we took a look at revalidatePath. In this chapter we cover the other…

0
↗ Quelle (dev.to)
Reagiere als Erste:r — dein Feedback zählt!

We've been covering on-demand revalidation. Three functions allow you to revalidate on demand:




  1. revalidatePath

  2. revalidateTag

  3. updateTag



In the previous chapter, we took a look at revalidatePath. In this chapter we cover the other two:




revalidateTag allows you to invalidate cached data on-demand for a specific cache tag.



updateTag allows you to update cached data on-demand for a specific cache tag from within Server Actions.




We target cached data, that is data cache entries.






Create a tag



A cache tag (string[]) is a tag you add to a data fetch:




fetch(url, { next: { tags: ['posts', 'post-a'] } });






Note: there is a second option to create a tag: cacheTag. We will cover this in a later chapter.



Tagging a fetch will add the data to the data cache with those tag(s). You can then call revalidateTag or updateTag to revalidate or update the data.






updateTag






updateTag(tag: string): void;







  • Takes one argument: a single tag.

  • Can only be called from server actions.

  • Revalidates data as read-your-own-writes.



This should sound familiar. A function called from a server action performs a read-your-own-writes revalidation. Note that updateTag cannot be called from a route handler.






revalidateTag






revalidateTag(tag: string, profile: string | { expire?: number }): void;







  • First argument: a single tag.

  • Second argument (profile): 'max' or { expire: 0 }

  • Use it in route handlers.

  • Don't use it in server actions (you can, but use updateTag instead).



revalidateTag is a bit weird because its functionality seems to overlap with updateTag and that's true. updateTag is a recent addition to Next and it takes over some of the functionality of revalidateTag. However, for legacy support, revalidateTag keeps its original functionality. The rule is simple:





  • route handlers -> revalidateTag


  • server actions -> updateTag



It gets a bit weirder with the second argument of revalidateTag:




// inside route handler
revalidateTag('post-a', 'max'); // -> stale while revalidate
revalidateTag('post-a', { expire: 0 }); // -> read your own writes






So, when called from within a route handler, revalidateTag can revalidate via SWR or RYOW. revalidatePath can only do stale while revalidate.






Full route cache



revalidateTag and updateTag target the data cache, tagged data cache entries. But what happens with the full route cache - statically rendered routes? The short answer is as expected.






revalidateTag(tag, "max")(swr) in a static route



When calling revalidateTag(tag, "max") from a route handler, Next will mark the tagged data cache entry as stale. Any statically rendered routes that "depend" on this cache tag, will also be marked as stale. Note: no updates have been made at this point.



When Next receives a new request for a route that depends on the invalidated cache tag, it will serve the stale content and update the data cache and full route cache in the background. Only the next request will be served this now-fresh content. This is pure SWR. We've covered this. Let's write a test.



Note: the examples are available on github. We make a new route handler that will call revalidateTag. As before, we will hit this route handler directly to simulate an external call:




localhost:3000/revalidate/api/revalidateTag?tag=post-42&profile=max






This time we pass 2 searchParams: a tag and a profile value. This is our route handler:




// app/revalidate/api/revalidateTag/route.ts

import type { NextRequest } from 'next/server';
import { revalidateTag } from 'next/cache';

export async function GET(request: NextRequest) {
const tag = request.nextUrl.searchParams.get('tag');
const profileParam = request.nextUrl.searchParams.get('profile');
const profile: 'max' | { expire: 0 } = profileParam
? profileParam === 'expire'
? { expire: 0 }
: 'max'
: 'max';

if (tag) {
revalidateTag(tag, profile);
return Response.json({ revalidated: true });
}

return Response.json({
revalidated: false,
message: 'Missing tag to revalidate',
});
}






We also create a route for some post components:




// app/revalidate/tag/max/page.tsx

export default function Page() {
return (
<>
<Post postId={41} fetchOptions={{}} />
<Post
postId={42}
fetchOptions={{ next: { revalidate: 1800, tags: ['post-42'] } }}
/>
<Post postId={43} fetchOptions={{ cache: 'force-cache' }} />
</>
);
}






And we run a test:




[action]
next build
next start
visit localhost:3000/revalidate/api/revalidateTag?tag=post-42&profile=max
get revalidated response
visit /revalidate/tag/max

[expect]
✅ pass: all time stamps to be equal (from build)

[action]
refresh page

[expect]
✅ pass: post 41 to have updated time stamp
✅ pass: post 42 to have updated time stamp
✅ pass: post 43 not to have changed






We revalidated post 42. We were served stale content on the first request. It updated in the background. On a new request (refresh), it served fresh data. Post 43 did not update. This is as expected. Post 41 also updated. This may or may not surprise you. Post 41 is a fetch with the auto cache option, which means no cache. When we revalidated post-42, it triggered a data cache and full route cache update. The last one made a new fetch for post 41 and that is why it updated.



We proved that revalidateTag only revalidates the tagged cache and behaves SWR when called from a route handler with the argument 'max'.






revalidateTag(tag, {expire: 0})(RYOW) in a static route



Here is a new example. We're calling revalidateTag with arguments 'post-45' and { expire: 0 } from a router handler. We expect read your own writes. We reuse the same route handler from the previous example but update the searchParams to tag "post-45" and profile "expire":




localhost:3000/revalidate/api/revalidateTag?tag=post-45&profile=expire






And we create a new test route:




// app/revalidate/tag/expire/page.tsx

import Post from '@/components/Post';

export default function Page() {
return (
<>
<Post postId={44} fetchOptions={{}} />
<Post
postId={45}
fetchOptions={{ next: { revalidate: 1800, tags: ['post-45'] } }}
/>
<Post postId={46} fetchOptions={{ cache: 'force-cache' }} />
</>
);
}









[action]
next build
next start
visit localhost:3000/revalidate/api/revalidateTag?tag=post-45&profile=expire
get revalidated response
visit /revalidate/tag/expire

[expect]
✅ pass: post 44 and post 45 to have same time stamp (updated)
✅ pass: post 46 to have different time stamp (from build)






My test may be a bit confusing. We hit the endpoint and expect RYOW. The data cache for post-45 updates, this triggers an update for route revalidate/tag/expires, which in turn refetches post 44 (auto cache option). There is no refetch for 46 because the data cache is not stale. Thus, 44 and 45 were updated while 46 kept the timestamp from build.



Note: we could've first visited the test route /revalidate/tag/expire, looked at the time, then hit the api endpoint and returned to our test route. But, that would've caused problems with the client-side router cache and the test would've failed. This is a problem you have to consider in real live world apps as well.



In short, we confirmed that calling revalidateTag with option { expire: 0 } does revalidate as read your own writes.






updateTag()(RYOW) in a server action



We're working with server actions and read your own writes now. Server actions are event driven. A user clicks a button and expects a change in the UI. Notice how this differs from the previous example. That was an outside action, this is internal. We expect an immediate update.



Here is our example:




// app/revalidate/tag/updateTag/page.tsx

export default function page() {
return (
<>
<div className='mb-8'>
<Post postId={47} fetchOptions={{}} />
<Post
postId={48}
fetchOptions={{ next: { revalidate: 1800, tags: ['post-48'] } }}
/>
<Post postId={49} fetchOptions={{ cache: 'force-cache' }} />
</div>
<UpdateTagActionButton tag='post-48' />
</>
);
}






So, 3 posts and a button: button -> server action -> updateTag.



updateTag in action



Note: not 100% clear but 2 clicks.



Everything updates as expected. 47 (no cache) and 48 updated, 49 (force cache) did not. We also made a copy of this route without the button:




// app/revalidate/tag/updateTag-copy/page.tsx

export default function page() {
return (
<>
<Post postId={47} fetchOptions={{}} />
<Post
postId={48}
fetchOptions={{ next: { revalidate: 1800, tags: ['post-48'] } }}
/>
<Post postId={49} fetchOptions={{ cache: 'force-cache' }} />
</>
);
}






We clicked the button in the route revalidate/tag/updateTag. Then we visited our full route cache for the route copy:




.next\server\app\revalidate\tag\updateTag-copy.html






We found the prerendered HTML and saw that the timestamps were still the old ones on all posts. Next, we actually visited the route: revalidate/tag/updateTag-copy and found that all timestamps were updated. Upon revisiting the prerendered files, we saw that they had been updated as well.



So, this is interesting. The route where the server action was called from was updated immediately. Other routes that depend on the updated tag are marked as stale and get updated when a request is made for that route. No stale content is served. The server rerenders the route at request time, serves the fresh content and saves it in the full route cache. In other words, for other routes, the update is only made at request time. Hitting updateTag does not immediately update all routes statically.






Summary



revalidateTag invalidates a cache tag. Only call it from inside a route handler.




revalidateTag('tag', 'max'); // -> stale while revalidate
revalidateTag('tag', { expire: 0 }); // -> read-your-own-writes






Depending on the second parameter ("max" or "{ expire: 0 }"), it will also update all affected routes in the full route cache as stale while revalidate or read-your-own-writes.



updateTag invalidates a cache tag. Only call it from a server action. It invalidates cache tag and all affected routes in the full route cache as read-your-own-writes. However, only the route the server action was called from will immediately be statically rerendered. Other affected routes will only be statically rerendered at request time.






Some notes




  • The Next docs explicitly mention that it's fine to call both revalidatePath and updateTag together to ensure data consistency.

  • Caching and revalidation work completely differently in development mode, so be careful.



If you want to support my writing, you can donate with paypal.

1. Sofort-Triage & Abwehrmaßnahmen

SOC Incident Playbook: Remote Code Execution (RCE) Defense
Syntax validiert (0 Fehler)
title: Detect Exploitation - revalidateTag & updateTag In NextJs
id: 49c018f6-818a-44da-991c-5295c80bd501
status: experimental
description: Automatisch generierte SIEM-Erkennungsregel basierend auf CTI Intelligence
references:
  - https://tsecurity.de/
author: iShareStuff CTI Automated Detection Engine
date: 2026-09-26
logsource:
  category: network_connection
  product: any
detection:
  selection:
      CommandLine|contains:
        - 'exploit'
  condition: selection
falsepositives:
  - Legitime administrative Zugriffe oder Penetrationstests
level: high
tags:
  - attack.initial_access
Syntax validiert (0 Fehler)
rule CTI_Threat_Indicator {
    meta:
        author = "iShareStuff CTI Automated Detection Engine"
        date = "2026-09-26"
        description = "YARA Signature for "
    strings:
        $str = "revalidateTag & updateTag In N" ascii wide
    condition:
        any of them
}
Syntax validiert (0 Fehler)
index=security sourcetype IN ("cisco:asa", "pan:traffic", "zeek_conn", "suricata", "WinEventLog:Security")
("revalidateTag  updateTag In NextJs")
| stats count earliest(_time) as first_seen latest(_time) as last_seen by src_ip, dest_ip, dest_host, signature
| eval first_seen=strftime(first_seen, "%Y-%m-%d %H:%M:%S"), last_seen=strftime(last_seen, "%Y-%m-%d %H:%M:%S")
| sort - count
Syntax validiert (0 Fehler)
message: "*revalidateTag  updateTag In NextJs*"
Syntax validiert (0 Fehler)
CommonSecurityLog
| where Message has "revalidateTag  updateTag In NextJs"
| summarize EventCount = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by SourceIP, DestinationIP, DestinationPort, Activity
| extend DetectionRule = "iShareStuff-CTI-Compiled"
| sort by EventCount desc

2. Cyber Threat Intelligence & Forensik

🎯
MITRE ATT&CK Matrix Navigator 14 Taktiken
Reconnaissance
-
Resource Development
-
Initial Access
Execution
Persistence
-
Privilege Escalation
Defense Evasion
Credential Access
-
Discovery
-
Lateral Movement
-
Collection
-
Command and Control
Exfiltration
-
Impact
tsecurity.de Cognitive Threat RAG
Fokus-Vektor:

Kognitive Analyse für identifizierte Bedrohung: Erhöhte Bedrohungslage im Bereich revalidateTag &amp; updateTag In NextJs.... Basierend auf 368k Vektor-Korrelationen werden sofortige Isolationsmaßnahmen für betroffene Endpunkte empfohlen.

🛡️ Angriffsfläche & Exposure

Netzwerk/Remote-Zugriff ohne Vorauthentifizierung möglich.

⚡ Empfohlene Sofortmaßnahmen
  • 1. Perimeter-Inspektion: Relevante Portfreigaben und exponierte Endpunkte unverzüglich scannen.
  • 2. Patch-Applikation: Hersteller-Hotfix einspielen oder betroffene Daemons in isolierte DMZ-Segmente überführen.
  • 3. Telemetrie & EDR-Alerts: Prozessaufrufe und Child-Processes auf anomale Shell-Spawns überwachen.
🔗 Semantisch verwandte Zero-Days MariaDB 11.7 VEC
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten revalidateTag & updateTag In NextJs

Thematisch verwandte Begriffe: revalidateTag, updateTag, NextJs · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Zum Aktualisieren ziehen
ZERO-DAY CVE-2026-86066 | Horilla is an HR and CRM software. Prior to 2.0.0, approve_validate_atte…
Advisory →
tsecurity.de Icon
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag