Documentation
Documentation
Introduction

Getting Started

Getting started
Getting StartedInstallationQuick StartProject Structure

Configuration

Configuration
ConfigurationEnvironment ConfigurationEdge ConfigDatabaseAuth SecretStripeFirebaseStorageGoogle Maps And Cloud Service AccountOAuth ProvidersEmail DeliverySentryFeature Flags

Architecture

Architecture
Architecture OverviewTech StackoRPC MiddlewareDesign Principles

Patterns

Patterns
Code Patterns & ConventionsFeature ModulesError HandlingType Safety

Database

Database
DatabaseSetupSchema DefinitionDatabase OperationsMigrationsCaching
Data Tables

API

oRPCProceduresRoutersoRPC Proxy Setup
APIsOpenAPIREST Endpoints

Auth & Access

AuthenticationConfigurationOAuth ProvidersRolesSession Management
AuthorizationUser RolesPermissions

Routing & i18n

RoutingDeclarative RoutingNavigation
InternationalizationTranslationsLocale Routing

Components & UI

ComponentsButtonsFormsNavigationDialogs
StylesTailwind CSSThemingTypography

Storage

Storage
StorageConfigurationUsageBuckets
Stripe Billing

Extra

Caching

Templates

Templates
Template GuidesCreate New FeatureCreate New PageCreate Database TableCreate oRPC RouterAdd Translations

Development

Development
DevelopmentCommandsAI AgentsBest Practices
Pulling Updates

Caching

Use Next.js "use cache" directive with cache life, tags, and revalidation

This template uses Next.js caching with the "use cache" directive for expensive server-side reads.

When to use it

Use "use cache" for:

  • Server Components that fetch mostly-static or semi-static data
  • Server-side async functions reused across routes
  • Expensive database/API reads where small staleness is acceptable

Enablement

next.config.ts should include:

import type { NextConfig } from "next";

const nextConfig: NextConfig = {
  experimental: {
    useCache: true,
  },
};

export default nextConfig;

Minimal reference example

import { cacheLife, cacheTag } from "next/cache";

async function getProducts() {
  "use cache";
  cacheLife("minutes");
  cacheTag("products");

  // Example expensive read
  return db.query.products.findMany();
}

export default async function ProductsPage() {
  const products = await getProducts();

  return (
    <ul>
      {products.map((product) => (
        <li key={product.id}>{product.name}</li>
      ))}
    </ul>
  );
}

Revalidation after writes

Use revalidateTag("products", "max") after mutations:

"use server";

import { revalidateTag } from "next/cache";

export async function createProduct(input: { name: string }) {
  await db.insert(products).values(input);
  revalidateTag("products", "max");
}

With "max", Next.js uses stale-while-revalidate behavior: stale data can be served first, then refreshed in the background.

Practical notes

  • Keep tags stable and domain-based (for example, "products", "users").
  • Put "use cache" at the top of the cached function/component body.
  • Use this for server-side expensive reads, not request-specific user-private reads.

On this page

When to use it
Enablement
Minimal reference example
Revalidation after writes
Practical notes