@cloudflare/next-on-pages

repository·main·Indexed 23 days ago

https://github.com/cloudflare/next-on-pages

A CLI toolset for building, developing, and deploying Next.js applications on the Cloudflare Pages platform. It includes the next-dev submodule for local development with simulated Cloudflare bindings (KV, R2, Durable Objects) via getRequestContext, and eslint-plugin-next-on-pages for best practice enforcement. Note: This package is deprecated in favor of the OpenNext Cloudflare adapter.

Tokens
17.4K
Snippets
32
Records
97
Agent score
78%

What's inside @cloudflare/next-on-pages

  1. Overview of @cloudflare/next-on-pages

    main

    @cloudflare/next-on-pages is a CLI tool designed to build, develop, and deploy Next.js applications specifically for the Cloudflare Pages platform.

    It is accompanied by several supporting packages:

    • eslint-plugin-next-on-pages: An ESLint plugin to improve developer experience and efficiency when using the tool.
    • next-dev: A submodule (included in the main package) used for local development.
  2. How source route matching and overrides work

    main

    When a source route matches a request, several actions occur to modify the request or response:

    1. Matching Criteria

    A route matches if:

    • The request method is identical.
    • The path matches (supporting regular expressions or exact strings).
    • Required fields are present/absent as specified in the config.

    2. Overrides and Internationalization (i18n)

    • Overrides: Matching routes can override the current response headers and status codes.
    • i18n: For sub-path or domain routing, the router checks for locale matches. It prioritizes locale information found in cookies over the Accept-Language header. If a locale match is found, a redirect is applied and routing exits.

    3. Middleware

    Middleware runs during the none phase.

    • Response headers from middleware are applied to the request and response.
    • If middleware performs a rewrite, the current path is updated.
    • If middleware fails, the router enters the error phase.

    4. Headers and Status Codes

    Source routes can specify headers and status codes. If a route has an important: true property, those headers take precedence over all other headers on the final response object.

  3. How lazy loading works in @cloudflare/next-on-pages

    main

    To optimize performance and reduce memory usage, @cloudflare/next-on-pages uses a lazy loading strategy. Instead of evaluating the entire application code at once, the generated Cloudflare Worker only imports the specific route code required to handle an incoming request.

    When you build your application, the CLI categorizes the vercel build output into two types of files:

    1. Route files: These export functions that produce a route result (e.g., a server-side rendered page or an API route response) for a specific request.
    2. Chunk files: These contain shared code deduplicated across different routes to reduce the overall JavaScript bundle size.

    The execution flow works as follows:

    • The main _worker.js uses dynamic imports (import()) to load only the necessary Route file when a request matches a route.
    • The Route file then uses static imports (import * from) to pull in the specific Chunk files it requires.

    This ensures that code is only evaluated and run when it is actually needed to handle a request.

    flowchart TD
        subgraph _worker.js
         worker["default export { fetch }"]:::worker
        end
    
        _worker.js -.-> routeA
        _worker.js -.-> routeB
        _worker.js -.-> ...routes...
        _worker.js -.-> apiRouteX
        _worker.js -.-> apiRouteY
    
        routeA --> chunk1
        routeA --> chunk2
        routeB --> chunk1
        routeB --> chunk3
        ...routes...:::multi --> ...chunks...:::multi
        apiRouteX --> chunk5
        apiRouteX --> chunk3
        apiRouteX --> chunk6
        apiRouteY --> chunk6
        apiRouteY --> chunk4
    
        classDef multi opacity:0.8,stroke:transparent,fill:transparent
        classDef worker fill:transparent
  4. Understand Caching and Data Revalidation in @cloudflare/next-on-pages

    main

    @cloudflare/next-on-pages extends Next.js built-in functionality by providing support for data revalidation and caching for fetch requests via its router.

    Key behaviors:

    • Default Behavior: Caching is enabled by default, following standard Next.js behavior. To opt-out, follow the official Next.js documentation.
    • Persistence: The cache is persisted across deployments.
    • Responsibility: You are responsible for revalidating or purging the cache; @cloudflare/next-on-pages and Cloudflare Pages do not handle cache purging automatically.
  5. Handling Incremental Static Regeneration (ISR)

    main

    Next.js ISR (Incremental Static Regeneration) is not supported for the edge runtime. ISR relies on Node.js-based Prerender Functions that run in the background, which are incompatible with Cloudflare Pages.

    How to handle ISR in Next-on-Pages:

    • Fallback Behavior: If your build process generates prerendered pages, @cloudflare/next-on-pages will use the generated static fallback files. This allows your application to serve the ISR/prerendered pages correctly, but without the automatic regeneration aspect.
    • Recommended Alternative: Switch from ISR to Server Side Rendering (SSR) to ensure pages can be dynamically updated on the edge.
  6. How dynamic route rewrites work

    main

    During the rewrite phase, the system uses regular expressions defined in the build output configuration to map incoming URL paths to internal file paths and search parameters. This allows dynamic segments in a URL to be captured and passed to the underlying function or file.

    For example, a source route can capture a slug from a URL and transform it into a destination path that includes that slug as a query parameter.

    {
    	"src": "^/blog/(?<slug>[^/]+?)(?:/)?$",
    	"dest": "/blog/[slug]?slug=$slug"
    }
  7. Use Workers KV for global data storage

    main

    Workers KV is a low-latency, globally distributed key-value store. It is ideal for data that needs to be accessible worldwide.

    Characteristics:

    • Global Availability: Unlike the Cache API, KV storage is global, which affects how on-demand revalidation behaves.
    • Consistency: KV is eventually consistent; updates may take up to 60 seconds to reflect globally.
    • Management: Using KV allows you to easily inspect, invalidate, or purge cache content via the Cloudflare Dashboard KV UI.

    Recommendation: @cloudflare/next-on-pages recommends using the Workers KV storage solution for its ease of management and global availability.

  8. Understand the Next-on-Pages routing process

    main

    The routing system in next-on-pages is a custom implementation designed to emulate Vercel's routing behavior using the Vercel build output. The process follows these high-level steps:

    1. Initialize: The handler is called with the incoming request.
    2. Phase Iteration: The router iterates through different routing phases (starting with none) defined in the build output configuration.
    3. Source Route Matching: For each phase, the router checks every source route to see if it matches the current request path and method.
    4. Modification: If a match is found, the router applies response modifiers (headers, status codes, redirects) and potentially rewrites the path.
    5. Execution: Once a final match is determined, the router either runs the matched function (for dynamic routes) or fetches the matched static asset.
    6. Response: The final response, including any applied headers and search parameters, is returned to the client.

    To prevent infinite loops caused by misconfigured build output records, the system includes a phase-checking counter that resets per request. If the counter exceeds a threshold, it indicates a configuration error.

  9. How routing phases work in Next-on-Pages

    main

    Routing is organized into distinct phases. The router moves through these phases to find a match or handle errors.

    Key Phases

    • none: The starting phase where middleware is executed.
    • miss: Triggered when no file matches the requested path in the build output. If a file is eventually found, the router may transition to the hit phase.
    • hit: The phase where a successful match is finalized and headers are updated.
    • error: Entered if middleware or route checking fails.
    • filesystem and rewrite: Phases triggered when a source route has the check: true property, used to verify the existence of a rewritten path.

    Phase Transition Logic

    • If a match is found in the hit phase, routing is complete.
    • If the current phase is miss and no file is found, the status is set to 404. If a file is found, the router moves to the hit phase.
    • If a route specifies a destination (rewrite) and the check property is true, the router may jump back to the none phase to re-process the new path, or move to filesystem/rewrite phases.
  10. Understand the Next.js routing phases on Cloudflare Pages

    main

    To replicate Vercel's routing behavior, the Cloudflare Pages worker processes requests through several sequential phases. The routing process determines whether a request should be handled by a server-side function or served as a static file. The phases are:

    1. none: The initial phase. Handles next.config.mjs configurations like headers, redirects, and beforeFiles rewrites. It also executes Middleware and rewrites RSC requests to RSC pages. It checks for static assets and non-dynamic routes.
    2. filesystem: Entered if no match is found in the none phase. Handles afterFiles rewrites from next.config.mjs and checks the build output for those specific rewrites.
    3. rewrite: Handles dynamic routes using regular expressions. It transforms paths into internal file names with search parameters (e.g., turning /blog/hello-world into /blog/[slug]?slug=hello-world).
    4. resource: The final mapping stage. Handles fallback rewrites from next.config.mjs and checks for any remaining routes. It sets the status to 404 for unmatched routes.
    5. miss: Occurs when no routes match, resulting in a 404 response.
    6. error: A specialized phase used to map requests to custom error pages based on status codes.
    7. hit: The final phase entered after matching is complete (even if the match results in a miss). It applies final headers like x-matched-path.