@mrjscrap/next-on-pages v0.2.0-hack8
@cloudflare/next-on-pages
Reference:
Quick Start
- npx create-next-app@latest my-app- Note that if you elect to use eslint, there are a couple of places you need to add return types to make the default template pass the pre-build checks. 
- cdinto the new directory (e.g.- cd my-app)
- npm install -D @cloudflare/next-on-pages vercel
- Configure the project to use the Edge Runtime: - Replace - pages/api/hello.tswith the following:- // Next.js Edge API Routes: https://nextjs.org/docs/api-routes/edge-api-routes import type { NextRequest } from "next/server"; export const config = { runtime: "experimental-edge", }; export default async function handler( req: NextRequest ): Promise<Response> { return new Response(JSON.stringify({ name: "John Doe" }), { status: 200, headers: { "Content-Type": "application/json", }, }); }
- Add the following to - next.config.js:- /** @type {import('next').NextConfig} */ const nextConfig = { + experimental: { + runtime: "experimental-edge", + }, reactStrictMode: true, swcMinify: true, }; module.exports = nextConfig;
 
- git commitand- git pushto a GitHub/GitLab repository.
- Create a Pages project, connect that repository, and select "Next.js" from the framework preset list. - Option - Value - Build command - npx @cloudflare/next-on-pages --experimental-minify- Build output directory - .vercel/output/static
- Add a - NODE_VERSIONenvironment variable set to- 14or greater.
- In the Pages project Settings > Functions > Compatibility Flags, add the - transformstream_enable_standard_constructorand- streams_enable_constructorsflags. These will not be necessary once they graduate to be on by default on 2022-11-30's compatibility date.
- The project should now be ready to deploy. Create a new deployment. 
@cloudflare/next-on-pages CLI
⚡️ @cloudflare/next-to-pages CLI
⚡️
⚡️ Usage: npx @cloudflare/next-to-pages [options]
⚡️
⚡️ Options:
⚡️
⚡️   --help:                Shows this help message
⚡️
⚡️   --skip-build:          Doesn't run 'vercel build' automatically
⚡️
⚡️   --experimental-minify: Attempts to minify the functions of a project (by de-duping webpack chunks)
⚡️
⚡️   --watch:               Automatically rebuilds when the project is edited
⚡️
⚡️
⚡️ GitHub: https://github.com/cloudflare/next-on-pages
⚡️ Docs: https://developers.cloudflare.com/pages/framework-guides/deploy-a-nextjs-site/Local testing
In one terminal, run npx @cloudflare/next-on-pages --watch, and in another npx wrangler pages dev .vercel/output/static --compatibility-flags=streams_enable_constructors. We hope to soon make improvements to the refersh speed.
Build Output Configuration
| config.jsonproperty | Support | 
|---|---|
| version | 3 | 
| routes src | ✅ | 
| routes dest | 🔄 | 
| routes headers | 🔄 | 
| routes methods | ✅ | 
| routes continue | 🔄 | 
| routes caseSensitive | ✅ | 
| routes check | 🔄 | 
| routes status | 🔄 | 
| routes has | ✅ | 
| routes missing | ✅ | 
| routes locale | 🔄 | 
| routes middlewarePath | ✅ | 
| images | ❌ (see Cloudflare's Image Resizing documentation) | 
| wildcard | 🔄 | 
| overrides | 🔄 | 
| cache | ❌ | 
Examples
Next.js 13's app Directory
Add the following to next.config.js:
/** @type {import('next').NextConfig} */
const nextConfig = {
  experimental: {
    runtime: "experimental-edge",
  + appDir: true,
  },
  reactStrictMode: true,
  swcMinify: true,
};
module.exports = nextConfig;If you're following the Next.js 12 → 13 Upgrade Guide, delete any ./pages/_app.tsx and ./pages/index.tsx files and replace with ./app/layout.tsx and ./app/page.tsx:
// ./app/layout.tsx
import "../styles/globals.css";
import { FC } from "react";
const RootLayout: FC<{
  children: React.ReactNode;
}> = ({
  // Layouts must accept a children prop.
  // This will be populated with nested layouts or pages
  children,
}) => {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  );
};
export default RootLayout;// ./app/page.tsx
import { FC } from "react";
import styles from "../styles/Home.module.css";
const Home = async (): Promise<ReturnType<FC>> => {
  const uuid = await fetch("https://uuid.rocks/plain").then(
    async (response) => await response.text()
  );
  return (
    <div className={styles.container}>
      <main className={styles.main}>
        <h1 className={styles.title}>
          Welcome to <a href="https://nextjs.org">Next.js!</a>
        </h1>
        <p className={styles.description}>
          Get started by editing{" "}
          <code className={styles.code}>pages/index.tsx</code>
        </p>
        <p className={styles.description}>
          Here's a server-side UUID:
          <code className={styles.code}>{uuid}</code>
        </p>
      </main>
    </div>
  );
};
export default Home;Edge API Routes
// ./pages/api/some_route.ts
import type { NextRequest } from "next/server";
export const config = {
  runtime: "experimental-edge",
};
export default async function handler(req: NextRequest) {
  return new Response(
    JSON.stringify({
      name: process.env.NEXT_RUNTIME,
    }),
    {
      status: 200,
      headers: {
        "content-type": "application/json",
      },
    }
  );
}Server-side rendering (SSR) pages with getServerSideProps()
// ./pages/ssr.tsx
import type { NextPage } from "next";
import Head from "next/head";
import styles from "../styles/Home.module.css";
export const config = {
  runtime: "experimental-edge",
};
export const getServerSideProps = async () => {
  return {
    props: {
      runtime: process.env.NEXT_RUNTIME,
      uuid: await fetch("https://uuid.rocks/plain").then((response) =>
        response.text()
      ),
    },
  };
};
const Home: NextPage<{ runtime: string; uuid: string }> = ({
  runtime,
  uuid,
}) => {
  return (
    <div className={styles.container}>
      <Head>
        <title>Create Next App</title>
        <meta name="description" content="Generated by create next app" />
        <link rel="icon" href="/favicon.ico" />
      </Head>
      <main className={styles.main}>
        <h1 className={styles.title}>
          Welcome to{" "}
          <a href="https://nextjs.org">Next.js, running at the {runtime}!</a>
        </h1>
        <p className={styles.description}>
          Get started by editing{" "}
          <code className={styles.code}>pages/index.tsx</code>
        </p>
        <p className={styles.description}>
          Here's a server-side UUID:
          <code className={styles.code}>{uuid}</code>
        </p>
      </main>
    </div>
  );
};
export default Home;Middleware
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
// This function can be marked `async` if using `await` inside
export function middleware(request: NextRequest) {
  return NextResponse.redirect(new URL("/about-2", request.url));
}
export const config = {
  matcher: "/about/:path*",
};3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago