-
-
Notifications
You must be signed in to change notification settings - Fork 35
Understanding Implicit Tags and Revalidation in Next.js
Next.js's caching system, particularly with the App Router, can be complex due to its internal mechanisms and how it handles cache invalidation. This guide aims to clarify the concepts of implicit tags, the role of NEXT_CACHE_IMPLICIT_TAG_ID
, and the revalidation process. This should help you make informed decisions and contribute effectively to the community.
- Implicit Tags
-
NEXT_CACHE_IMPLICIT_TAG_ID
:"_N_T_"
-
Understanding
get
andrevalidateTag
- Step-by-Step Explanation of Revalidation
Implicit tags are automatically generated cache tags used internally by Next.js to manage cache invalidation for pages and layouts in the App Router. They help Next.js determine which cache entries must be invalidated when certain pages or layouts change.
Implicit tags are generated based on the routing hierarchy of your Next.js application. For example, for a page at /user/[id]/page.js
, the implicit tags for /user/123
will look like:
_N_T_/layout
_N_T_/user/layout
_N_T_/user/[id]/layout
_N_T_/user/[id]/page
_N_T_/user/123
These tags represent the nested layouts and pages, allowing Next.js to manage associated cache entries.
-
Fetch Tags: When using
fetch()
with caching options, you can specify explicit tags for cache invalidation. -
unstable_cache
Tags: Similarly,unstable_cache()
allows for explicit tagging. - Implicit Tags: These are additional, internally managed tags that do not include or replace your explicit tags. They work alongside them to ensure the integrity of the caching system.
NEXT_CACHE_IMPLICIT_TAG_ID
is a unique identifier used by Next.js to prefix implicit tags. The default value is "_N_T_"
. This prefix helps distinguish implicit tags from user-defined tags and ensures internal cache management processes function correctly.
NEXT_CACHE_IMPLICIT_TAG_ID
is considered an internal constant and is not part of the public API. It is intended for use within Next.js' core and may change without notice in future releases.
Implicit tags require different handling because:
- Internal Consistency: They ensure the internal caching mechanisms of Next.js operate without interference from user-defined tags.
- Avoiding Conflicts: Using a unique prefix prevents accidental collisions with tags you might define in your application.
When you call revalidateTag
, it signals Next.js that specific cached data associated with that tag must be revalidated. However, the actual cache invalidation doesn't happen immediately. Instead, it occurs the next time a get
operation accesses the cache. This deferred invalidation optimizes performance by avoiding unnecessary data fetching until it's needed.
-
Mark for Revalidation:
revalidateTag
adds the specified tag to a list of tags that require revalidation. -
Deferred Invalidation: The cache entry remains valid until the next
get
operation checks the cache. -
Cache Check: Upon a
get
, Next.js checks if any associated tags are marked for revalidation. - Invalidation and Refetch: If so, Next.js invalidates the cache entry and fetches fresh data.
Below is a detailed walkthrough of how revalidation works in Next.js, including implicit tags.
-
Initial Page Load
-
User Visits Page: A user accesses
/user/123
. -
Data Fetching: Next.js fetches data using
fetch()
orunstable_cache()
, caching it with explicit tags (if provided) and implicit tags. -
Caching:
- Fetch Cache: Stores the fetched data associated with any explicit tags and implicit tags.
- Page Cache: Stores the rendered page output.
-
User Visits Page: A user accesses
-
Triggering Revalidation
-
Data Change: The data for
user/123
changes on the server. -
Revalidation Request: An API route or background process calls
revalidatePath('/user/123')
. -
Revalidation Process:
-
Implicit Tag Identification: Next.js identifies implicit tags associated with
/user/123
, such as_N_T_/user/[id]/page
. - Tag Marking: These implicit tags are marked for revalidation.
-
Page Cache Deletion: The page cache for
/user/123
is invalidated immediately.
-
Implicit Tag Identification: Next.js identifies implicit tags associated with
-
Data Change: The data for
-
Subsequent Page Load
-
User Revisits Page: The user accesses
/user/123
again. -
Cache Access:
- Page Cache Miss: Since the page cache was invalidated, Next.js needs to re-render the page.
-
Fetch Cache Check: Next.js calls
get
to access the fetch cache.
-
Deferred Revalidation:
- Tag Check: Next.js checks if the implicit tags associated with the fetch cache are marked for revalidation.
- Cache Invalidation: If so, the fetch cache is invalidated.
- Data Refetch: Next.js fetches fresh data from the server.
- Page Rendering: The page is re-rendered with the updated data and cached for future requests.
-
User Revisits Page: The user accesses
Note: CacheHandler and TagStore are kept separate for clarity. In practice, TagStore is stored within the cache.
sequenceDiagram
participant User
participant Next.js Server
participant Backend
participant CacheHandler
participant TagStore
User->>Next.js Server: Request /user/123
Next.js Server->>Backend: Fetch data
Backend-->>Next.js Server: Return data
Next.js Server->>CacheHandler: Save fetch and page cache with tags
Next.js Server-->>User: Serve page
User->>Next.js Server: Calls revalidatePath('/user/123')
Next.js Server->>TagStore: Mark implicit tags for /user/123
Next.js Server->>CacheHandler: Invalidate page cache
User->>Next.js Server: Request /user/123 again
Next.js Server->>CacheHandler: Check page cache (miss)
Next.js Server->>CacheHandler: Check fetch cache
CacheHandler->>TagStore: Are tags marked for revalidation?
TagStore-->>CacheHandler: Yes
CacheHandler->>CacheHandler: Invalidate fetch cache
Next.js Server->>Backend: Fetch fresh data
Backend-->>Next.js Server: Return updated data
Next.js Server->>CacheHandler: Save new fetch and page cache
Next.js Server-->>User: Serve updated page