├── benchmarking
├── .gitignore
├── package.json
└── tsconfig.json
├── examples
├── playground14
│ ├── public
│ │ ├── .gitkeep
│ │ └── snipp
│ │ │ └── snipp.webp
│ ├── .dev.vars
│ ├── .env.development
│ ├── app
│ │ ├── page.js
│ │ ├── api
│ │ │ ├── request
│ │ │ │ └── route.ts
│ │ │ ├── env
│ │ │ │ └── route.ts
│ │ │ ├── buildid
│ │ │ │ └── route.ts
│ │ │ ├── instrumentation
│ │ │ │ └── route.ts
│ │ │ └── hello
│ │ │ │ └── route.ts
│ │ └── layout.js
│ ├── e2e
│ │ ├── playwright.config.ts
│ │ ├── playwright.dev.config.ts
│ │ └── head.spec.ts
│ ├── pages
│ │ ├── api
│ │ │ └── pages.ts
│ │ └── head.tsx
│ ├── open-next.config.ts
│ ├── middleware.js
│ ├── wrangler.jsonc
│ ├── worker.ts
│ ├── tsconfig.json
│ └── .gitignore
├── playground15
│ ├── public
│ │ ├── .gitkeep
│ │ ├── test.jpg
│ │ └── tomine.webp
│ ├── .dev.vars
│ ├── .env.development
│ ├── data.module.css
│ ├── data.js
│ ├── app
│ │ ├── page.js
│ │ ├── api
│ │ │ ├── request
│ │ │ │ └── route.ts
│ │ │ ├── signal
│ │ │ │ └── revalidate
│ │ │ │ │ └── route.ts
│ │ │ ├── instrumentation
│ │ │ │ └── route.ts
│ │ │ ├── buildid
│ │ │ │ └── route.ts
│ │ │ ├── env
│ │ │ │ └── route.ts
│ │ │ └── hello
│ │ │ │ └── route.ts
│ │ ├── image
│ │ │ └── page.tsx
│ │ ├── layout.js
│ │ ├── signal
│ │ │ └── page.tsx
│ │ ├── other-app
│ │ │ └── page.tsx
│ │ └── from-app
│ │ │ └── page.tsx
│ ├── e2e
│ │ ├── playwright.config.ts
│ │ ├── playwright.dev.config.ts
│ │ ├── image.test.ts
│ │ ├── cloudflare.spec.ts
│ │ └── head.spec.ts
│ ├── worker-configuration.d.ts
│ ├── middleware.js
│ ├── pages
│ │ └── head.tsx
│ ├── next.config.ts
│ ├── open-next.config.ts
│ ├── tsconfig.json
│ └── .gitignore
├── bugs
│ ├── gh-219
│ │ ├── .dev.vars
│ │ ├── src
│ │ │ └── app
│ │ │ │ ├── favicon.ico
│ │ │ │ └── globals.css
│ │ ├── open-next.config.ts
│ │ ├── public
│ │ │ ├── vercel.svg
│ │ │ ├── window.svg
│ │ │ └── file.svg
│ │ ├── e2e
│ │ │ ├── playwright.config.ts
│ │ │ └── base.spec.ts
│ │ ├── postcss.config.mjs
│ │ ├── next.config.ts
│ │ ├── wrangler.jsonc
│ │ ├── eslint.config.mjs
│ │ ├── tailwind.config.ts
│ │ └── tsconfig.json
│ ├── gh-223
│ │ ├── .eslintrc.json
│ │ ├── app
│ │ │ ├── favicon.ico
│ │ │ ├── api
│ │ │ │ └── image
│ │ │ │ │ └── route.ts
│ │ │ ├── layout.tsx
│ │ │ └── globals.css
│ │ ├── open-next.config.ts
│ │ ├── e2e
│ │ │ ├── playwright.config.ts
│ │ │ └── base.spec.ts
│ │ ├── postcss.config.mjs
│ │ ├── next.config.mjs
│ │ ├── wrangler.jsonc
│ │ ├── tailwind.config.ts
│ │ └── public
│ │ │ └── vercel.svg
│ └── gh-119
│ │ ├── .eslintrc.json
│ │ ├── app
│ │ ├── favicon.ico
│ │ ├── fonts
│ │ │ ├── GeistVF.woff
│ │ │ └── GeistMonoVF.woff
│ │ └── globals.css
│ │ ├── open-next.config.ts
│ │ ├── public
│ │ ├── vercel.svg
│ │ ├── window.svg
│ │ └── file.svg
│ │ ├── e2e
│ │ ├── playwright.config.ts
│ │ └── base.spec.ts
│ │ ├── postcss.config.mjs
│ │ ├── next.config.ts
│ │ ├── wrangler.jsonc
│ │ ├── tailwind.config.ts
│ │ └── tsconfig.json
├── e2e
│ ├── app-pages-router
│ │ ├── .env
│ │ ├── app
│ │ │ ├── parallel
│ │ │ │ ├── page.tsx
│ │ │ │ ├── @a
│ │ │ │ │ ├── a-page
│ │ │ │ │ │ └── page.tsx
│ │ │ │ │ └── page.tsx
│ │ │ │ └── @b
│ │ │ │ │ ├── b-page
│ │ │ │ │ └── page.tsx
│ │ │ │ │ └── page.tsx
│ │ │ ├── albums
│ │ │ │ ├── @modal
│ │ │ │ │ ├── default.tsx
│ │ │ │ │ └── (.)[album]
│ │ │ │ │ │ └── page.tsx
│ │ │ │ ├── [album]
│ │ │ │ │ ├── page.tsx
│ │ │ │ │ └── [song]
│ │ │ │ │ │ └── page.tsx
│ │ │ │ ├── layout.tsx
│ │ │ │ └── page.tsx
│ │ │ ├── ssr
│ │ │ │ ├── loading.tsx
│ │ │ │ ├── layout.tsx
│ │ │ │ └── page.tsx
│ │ │ ├── redirect-destination
│ │ │ │ └── page.tsx
│ │ │ ├── api
│ │ │ │ ├── client
│ │ │ │ │ └── route.ts
│ │ │ │ └── host
│ │ │ │ │ └── route.ts
│ │ │ ├── ssg
│ │ │ │ └── page.tsx
│ │ │ ├── server-actions
│ │ │ │ └── page.tsx
│ │ │ ├── isr
│ │ │ │ └── page.tsx
│ │ │ ├── image-optimization
│ │ │ │ └── page.tsx
│ │ │ ├── rewrite-destination
│ │ │ │ └── page.tsx
│ │ │ ├── layout.tsx
│ │ │ └── globals.css
│ │ ├── README.md
│ │ ├── postcss.config.js
│ │ ├── public
│ │ │ ├── favicon.ico
│ │ │ └── static
│ │ │ │ ├── frank.webp
│ │ │ │ └── corporate_holiday_card.jpg
│ │ ├── e2e
│ │ │ ├── playwright.config.ts
│ │ │ ├── playwright.turbopack.config.ts
│ │ │ ├── skip_trailing.test.ts
│ │ │ ├── host.test.ts
│ │ │ ├── headers.test.ts
│ │ │ └── middleware.test.ts
│ │ ├── open-next.turbopack.config.ts
│ │ ├── pages
│ │ │ ├── _app.tsx
│ │ │ ├── _document.tsx
│ │ │ ├── api
│ │ │ │ └── hello.ts
│ │ │ ├── pages_ssr
│ │ │ │ └── index.tsx
│ │ │ └── pages_isr
│ │ │ │ └── index.tsx
│ │ ├── next.config.ts
│ │ ├── open-next.config.ts
│ │ ├── tailwind.config.ts
│ │ ├── .gitignore
│ │ └── wrangler.jsonc
│ ├── pages-router
│ │ ├── .env.production
│ │ ├── README.md
│ │ ├── public
│ │ │ ├── favicon.ico
│ │ │ └── static
│ │ │ │ └── frank.webp
│ │ ├── e2e
│ │ │ ├── playwright.config.ts
│ │ │ ├── playwright.turbopack.config.ts
│ │ │ ├── middleware.test.ts
│ │ │ ├── 404.test.ts
│ │ │ ├── trailing.test.ts
│ │ │ ├── i18n.test.ts
│ │ │ └── header.test.ts
│ │ ├── postcss.config.js
│ │ ├── open-next.turbopack.config.ts
│ │ ├── src
│ │ │ ├── pages
│ │ │ │ ├── _app.tsx
│ │ │ │ ├── api
│ │ │ │ │ ├── query.ts
│ │ │ │ │ ├── dynamic
│ │ │ │ │ │ ├── precedence
│ │ │ │ │ │ │ └── index.ts
│ │ │ │ │ │ ├── [slug].ts
│ │ │ │ │ │ ├── catch-all-optional
│ │ │ │ │ │ │ └── [[...slug]].ts
│ │ │ │ │ │ └── catch-all
│ │ │ │ │ │ │ └── [...slug].ts
│ │ │ │ │ ├── hello.ts
│ │ │ │ │ └── revalidate.ts
│ │ │ │ ├── fallback-intercepted
│ │ │ │ │ ├── static.tsx
│ │ │ │ │ ├── ssg.tsx
│ │ │ │ │ ├── [...slugs].tsx
│ │ │ │ │ └── [slug].tsx
│ │ │ │ ├── _document.tsx
│ │ │ │ ├── ssg
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── isr
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── ssr
│ │ │ │ │ └── index.tsx
│ │ │ │ └── fallback
│ │ │ │ │ └── [slug].tsx
│ │ │ └── middleware.ts
│ │ ├── open-next.config.ts
│ │ ├── wrangler.jsonc
│ │ └── .gitignore
│ ├── shared
│ │ ├── sst-env.d.ts
│ │ ├── components
│ │ │ ├── Album
│ │ │ │ ├── Album.tsx
│ │ │ │ ├── index.tsx
│ │ │ │ └── Song.tsx
│ │ │ └── Filler
│ │ │ │ └── index.tsx
│ │ └── package.json
│ ├── app-router
│ │ ├── README.md
│ │ ├── app
│ │ │ ├── og
│ │ │ │ └── page.tsx
│ │ │ ├── parallel
│ │ │ │ ├── page.tsx
│ │ │ │ ├── @a
│ │ │ │ │ ├── a-page
│ │ │ │ │ │ └── page.tsx
│ │ │ │ │ └── page.tsx
│ │ │ │ └── @b
│ │ │ │ │ ├── b-page
│ │ │ │ │ └── page.tsx
│ │ │ │ │ └── page.tsx
│ │ │ ├── albums
│ │ │ │ ├── @modal
│ │ │ │ │ ├── default.tsx
│ │ │ │ │ └── (.)[album]
│ │ │ │ │ │ └── page.tsx
│ │ │ │ ├── [album]
│ │ │ │ │ ├── page.tsx
│ │ │ │ │ └── [song]
│ │ │ │ │ │ └── page.tsx
│ │ │ │ ├── layout.tsx
│ │ │ │ └── page.tsx
│ │ │ ├── ssr
│ │ │ │ ├── loading.tsx
│ │ │ │ ├── layout.tsx
│ │ │ │ └── page.tsx
│ │ │ ├── revalidate-tag
│ │ │ │ ├── nested
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── page.tsx
│ │ │ │ └── layout.tsx
│ │ │ ├── redirect-destination
│ │ │ │ └── page.tsx
│ │ │ ├── rewrite-destination
│ │ │ │ └── page.tsx
│ │ │ ├── methods
│ │ │ │ ├── get
│ │ │ │ │ ├── redirect
│ │ │ │ │ │ └── route.ts
│ │ │ │ │ ├── dynamic-segments
│ │ │ │ │ │ └── [slug]
│ │ │ │ │ │ │ └── route.ts
│ │ │ │ │ ├── revalidate
│ │ │ │ │ │ └── route.ts
│ │ │ │ │ ├── static
│ │ │ │ │ │ └── route.ts
│ │ │ │ │ └── query
│ │ │ │ │ │ └── route.ts
│ │ │ │ └── post
│ │ │ │ │ ├── formdata
│ │ │ │ │ └── route.ts
│ │ │ │ │ └── cookies
│ │ │ │ │ └── route.ts
│ │ │ ├── api
│ │ │ │ ├── client
│ │ │ │ │ └── route.ts
│ │ │ │ ├── host
│ │ │ │ │ └── route.ts
│ │ │ │ ├── revalidate-path
│ │ │ │ │ └── route.ts
│ │ │ │ ├── revalidate-tag
│ │ │ │ │ └── route.ts
│ │ │ │ ├── auth
│ │ │ │ │ └── [...better-auth]
│ │ │ │ │ │ └── route.ts
│ │ │ │ └── after
│ │ │ │ │ ├── ssg
│ │ │ │ │ └── route.ts
│ │ │ │ │ └── revalidate
│ │ │ │ │ └── route.ts
│ │ │ ├── server-actions
│ │ │ │ └── page.tsx
│ │ │ ├── cookies
│ │ │ │ └── page.tsx
│ │ │ ├── isr
│ │ │ │ └── page.tsx
│ │ │ ├── headers
│ │ │ │ └── page.tsx
│ │ │ ├── config-redirect
│ │ │ │ ├── dest
│ │ │ │ │ └── page.tsx
│ │ │ │ └── page.tsx
│ │ │ ├── image-optimization
│ │ │ │ └── page.tsx
│ │ │ ├── layout.tsx
│ │ │ ├── globals.css
│ │ │ └── revalidate-path
│ │ │ │ └── page.tsx
│ │ ├── postcss.config.js
│ │ ├── public
│ │ │ ├── favicon.ico
│ │ │ └── static
│ │ │ │ ├── frank.webp
│ │ │ │ └── corporate_holiday_card.jpg
│ │ ├── e2e
│ │ │ ├── playwright.config.ts
│ │ │ ├── playwright.turbopack.config.ts
│ │ │ ├── host.test.ts
│ │ │ ├── isr.revalidate.test.ts
│ │ │ └── dynamic.catch-all.hypen.test.ts
│ │ ├── open-next.turbopack.config.ts
│ │ ├── tailwind.config.ts
│ │ └── .gitignore
│ ├── experimental
│ │ ├── src
│ │ │ ├── app
│ │ │ │ ├── favicon.ico
│ │ │ │ ├── api
│ │ │ │ │ └── revalidate
│ │ │ │ │ │ └── route.ts
│ │ │ │ ├── use-cache
│ │ │ │ │ ├── layout.tsx
│ │ │ │ │ ├── isr
│ │ │ │ │ │ └── page.tsx
│ │ │ │ │ └── fetch
│ │ │ │ │ │ └── page.tsx
│ │ │ │ ├── page.tsx
│ │ │ │ └── ppr
│ │ │ │ │ └── page.tsx
│ │ │ └── components
│ │ │ │ ├── static.tsx
│ │ │ │ └── dynamic.tsx
│ │ ├── README.md
│ │ ├── e2e
│ │ │ └── playwright.config.ts
│ │ ├── next.config.ts
│ │ └── tsconfig.json
│ └── utils.ts
├── middleware
│ ├── .env
│ ├── app
│ │ ├── about
│ │ │ └── page.tsx
│ │ ├── about2
│ │ │ └── page.tsx
│ │ ├── another
│ │ │ └── page.tsx
│ │ ├── rewrite
│ │ │ └── page.tsx
│ │ ├── clerk
│ │ │ └── route.ts
│ │ ├── redirected
│ │ │ └── page.tsx
│ │ ├── layout.tsx
│ │ ├── page.tsx
│ │ └── middleware
│ │ │ └── page.tsx
│ ├── public
│ │ └── favicon.ico
│ ├── open-next.config.ts
│ ├── e2e
│ │ ├── playwright.config.ts
│ │ ├── playwright.dev.config.ts
│ │ └── cloudflare-context.spec.ts
│ ├── next.config.mjs
│ ├── wrangler.jsonc
│ ├── .gitignore
│ └── tsconfig.json
├── ssg-app
│ ├── .dev.vars
│ ├── app
│ │ ├── favicon.ico
│ │ ├── globals.css
│ │ ├── page.module.css
│ │ ├── page.tsx
│ │ └── layout.tsx
│ ├── worker-configuration.d.ts
│ ├── e2e
│ │ └── playwright.config.ts
│ ├── open-next.config.ts
│ ├── next.config.ts
│ ├── wrangler.jsonc
│ └── tsconfig.json
├── next-partial-prerendering
│ ├── .prettierrc
│ ├── postcss.config.js
│ ├── types
│ │ └── review.d.ts
│ ├── app
│ │ ├── favicon.ico
│ │ ├── twitter-image.png
│ │ ├── opengraph-image.png
│ │ └── not-found.tsx
│ ├── e2e
│ │ └── playwright.config.ts
│ ├── public
│ │ ├── nextjs-icon-light-background.png
│ │ ├── patrick-OIFgeLnjwrM-unsplash.jpg
│ │ ├── eniko-kis-KsLPTsYaqIQ-unsplash.jpg
│ │ ├── prince-akachi-LWkFHEGpleE-unsplash.jpg
│ │ ├── yoann-siloine-_T4w3JDm6ug-unsplash.jpg
│ │ ├── guillaume-coupy-6HuoHgK7FN8-unsplash.jpg
│ │ └── alexander-andrews-brAkTCdnhW8-unsplash.jpg
│ ├── components
│ │ ├── product-best-seller.tsx
│ │ ├── cart-count.tsx
│ │ ├── product-low-stock-warning.tsx
│ │ ├── ping.tsx
│ │ ├── product-rating.tsx
│ │ ├── product-currency-symbol.tsx
│ │ ├── product-used-price.tsx
│ │ ├── product-estimated-arrival.tsx
│ │ ├── product-split-payments.tsx
│ │ └── product-review-card.tsx
│ ├── next.config.js
│ ├── open-next.config.ts
│ ├── wrangler.jsonc
│ ├── lib
│ │ └── delay.ts
│ └── .gitignore
├── common
│ ├── package.json
│ └── tsconfig.json
├── create-next-app
│ ├── .eslintrc.json
│ ├── src
│ │ └── app
│ │ │ ├── favicon.ico
│ │ │ ├── fonts
│ │ │ ├── GeistVF.woff
│ │ │ └── GeistMonoVF.woff
│ │ │ └── globals.css
│ ├── open-next.config.ts
│ ├── e2e
│ │ ├── playwright.config.ts
│ │ └── base.spec.ts
│ ├── postcss.config.mjs
│ ├── next.config.mjs
│ ├── wrangler.jsonc
│ ├── tailwind.config.ts
│ ├── public
│ │ └── vercel.svg
│ ├── tsconfig.json
│ └── .gitignore
├── vercel-blog-starter
│ ├── src
│ │ ├── app
│ │ │ ├── globals.css
│ │ │ └── _components
│ │ │ │ ├── section-separator.tsx
│ │ │ │ ├── container.tsx
│ │ │ │ ├── date-formatter.tsx
│ │ │ │ ├── markdown-styles.module.css
│ │ │ │ ├── header.tsx
│ │ │ │ ├── post-body.tsx
│ │ │ │ ├── post-title.tsx
│ │ │ │ ├── avatar.tsx
│ │ │ │ └── intro.tsx
│ │ ├── interfaces
│ │ │ ├── author.ts
│ │ │ └── post.ts
│ │ └── lib
│ │ │ ├── markdownToHtml.ts
│ │ │ └── constants.ts
│ ├── postcss.config.js
│ ├── public
│ │ ├── favicon
│ │ │ ├── favicon.ico
│ │ │ ├── favicon-16x16.png
│ │ │ ├── favicon-32x32.png
│ │ │ ├── mstile-150x150.png
│ │ │ ├── apple-touch-icon.png
│ │ │ ├── android-chrome-192x192.png
│ │ │ ├── android-chrome-512x512.png
│ │ │ ├── browserconfig.xml
│ │ │ └── site.webmanifest
│ │ └── assets
│ │ │ └── blog
│ │ │ ├── authors
│ │ │ ├── jj.jpeg
│ │ │ ├── joe.jpeg
│ │ │ └── tim.jpeg
│ │ │ ├── preview
│ │ │ └── cover.jpg
│ │ │ ├── hello-world
│ │ │ └── cover.jpg
│ │ │ └── dynamic-routing
│ │ │ └── cover.jpg
│ ├── next.config.mjs
│ ├── open-next.config.ts
│ ├── wrangler.jsonc
│ ├── .gitignore
│ └── tsconfig.json
├── prisma
│ ├── src
│ │ ├── app
│ │ │ ├── favicon.ico
│ │ │ └── page.tsx
│ │ └── lib
│ │ │ └── db.ts
│ ├── open-next.config.ts
│ ├── e2e
│ │ ├── playwright.config.ts
│ │ └── playwright.dev.config.ts
│ ├── prisma.config.ts
│ ├── schema.prisma
│ ├── populate.sql
│ ├── next.config.ts
│ ├── wrangler.jsonc
│ └── tsconfig.json
└── overrides
│ ├── d1-tag-next
│ ├── app
│ │ ├── favicon.ico
│ │ ├── globals.css
│ │ ├── action.ts
│ │ ├── page.module.css
│ │ └── components
│ │ │ └── revalidationButtons.tsx
│ ├── e2e
│ │ └── playwright.config.ts
│ ├── next.config.ts
│ ├── open-next.config.ts
│ └── tsconfig.json
│ ├── kv-tag-next
│ ├── app
│ │ ├── favicon.ico
│ │ ├── globals.css
│ │ ├── action.ts
│ │ ├── page.module.css
│ │ └── components
│ │ │ └── revalidationButtons.tsx
│ ├── e2e
│ │ └── playwright.config.ts
│ ├── next.config.ts
│ ├── open-next.config.ts
│ ├── wrangler.e2e.jsonc
│ └── tsconfig.json
│ ├── memory-queue
│ ├── app
│ │ ├── favicon.ico
│ │ ├── globals.css
│ │ ├── page.module.css
│ │ ├── page.tsx
│ │ └── layout.tsx
│ ├── e2e
│ │ └── playwright.config.ts
│ ├── next.config.ts
│ ├── open-next.config.ts
│ ├── wrangler.jsonc
│ └── tsconfig.json
│ ├── r2-incremental-cache
│ ├── app
│ │ ├── favicon.ico
│ │ ├── globals.css
│ │ ├── page.module.css
│ │ ├── page.tsx
│ │ └── layout.tsx
│ ├── e2e
│ │ └── playwright.config.ts
│ └── next.config.ts
│ └── static-assets-incremental-cache
│ ├── app
│ ├── favicon.ico
│ ├── globals.css
│ ├── action.ts
│ ├── page.module.css
│ └── components
│ │ └── revalidationButtons.tsx
│ ├── e2e
│ └── playwright.config.ts
│ ├── open-next.config.ts
│ ├── next.config.ts
│ └── wrangler.jsonc
├── packages
└── cloudflare
│ ├── .gitignore
│ ├── src
│ ├── cli
│ │ ├── templates
│ │ │ └── shims
│ │ │ │ ├── empty.ts
│ │ │ │ ├── fetch.ts
│ │ │ │ ├── env.ts
│ │ │ │ └── throw.ts
│ │ ├── build
│ │ │ └── utils
│ │ │ │ ├── normalize-path.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── version.ts
│ │ │ │ └── test-patch.ts
│ │ ├── utils
│ │ │ └── ask-confirmation.ts
│ │ └── project-options.ts
│ ├── api
│ │ └── index.ts
│ └── utils
│ │ └── get-package-templates-dir-path.ts
│ ├── env.d.ts
│ ├── templates
│ └── open-next.config.ts
│ └── tsconfig.json
├── .gitignore
├── .vscode
└── settings.json
├── .editorconfig
├── create-cloudflare
└── next
│ ├── .dev.vars
│ ├── .vscode
│ └── settings.json
│ ├── postcss.config.mjs
│ ├── public
│ ├── _headers
│ ├── window.svg
│ └── file.svg
│ ├── next.config.ts
│ ├── open-next.config.ts
│ ├── eslint.config.mjs
│ ├── src
│ └── app
│ │ └── globals.css
│ └── tsconfig.json
├── .prettierignore
├── .github
├── ISSUE_TEMPLATE
│ └── config.yml
└── workflows
│ └── checks.yml
├── .prettierrc
└── .changeset
├── config.json
└── README.md
/benchmarking/.gitignore:
--------------------------------------------------------------------------------
1 | results/
2 |
--------------------------------------------------------------------------------
/examples/playground14/public/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/playground15/public/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/cloudflare/.gitignore:
--------------------------------------------------------------------------------
1 | dist
2 |
--------------------------------------------------------------------------------
/examples/bugs/gh-219/.dev.vars:
--------------------------------------------------------------------------------
1 | NEXTJS_ENV=development
--------------------------------------------------------------------------------
/examples/e2e/app-pages-router/.env:
--------------------------------------------------------------------------------
1 | SOME_ENV_VAR=foo
--------------------------------------------------------------------------------
/examples/playground14/.dev.vars:
--------------------------------------------------------------------------------
1 | NEXTJS_ENV=development
--------------------------------------------------------------------------------
/examples/playground15/.dev.vars:
--------------------------------------------------------------------------------
1 | NEXTJS_ENV=development
--------------------------------------------------------------------------------
/examples/e2e/pages-router/.env.production:
--------------------------------------------------------------------------------
1 | SOME_PROD_VAR=bar
--------------------------------------------------------------------------------
/examples/middleware/.env:
--------------------------------------------------------------------------------
1 | CLERK_ENCRYPTION_KEY="key"
2 |
--------------------------------------------------------------------------------
/examples/playground15/.env.development:
--------------------------------------------------------------------------------
1 | TEST_ENV_VAR=TEST_VALUE
--------------------------------------------------------------------------------
/examples/ssg-app/.dev.vars:
--------------------------------------------------------------------------------
1 | MY_SECRET = "psst... this is a secret!"
2 |
--------------------------------------------------------------------------------
/examples/playground15/data.module.css:
--------------------------------------------------------------------------------
1 | .wrap {
2 | display: flex;
3 | }
4 |
--------------------------------------------------------------------------------
/packages/cloudflare/src/cli/templates/shims/empty.ts:
--------------------------------------------------------------------------------
1 | export default {};
2 |
--------------------------------------------------------------------------------
/packages/cloudflare/src/cli/templates/shims/fetch.ts:
--------------------------------------------------------------------------------
1 | export default fetch;
2 |
--------------------------------------------------------------------------------
/examples/next-partial-prerendering/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true
3 | }
4 |
--------------------------------------------------------------------------------
/examples/bugs/gh-223/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "next/core-web-vitals"
3 | }
4 |
--------------------------------------------------------------------------------
/examples/playground14/.env.development:
--------------------------------------------------------------------------------
1 | TEST_ENV_VAR=TEST_VALUE
2 | PROCESS_ENV_VAR=.ENV_FILE
--------------------------------------------------------------------------------
/packages/cloudflare/src/cli/templates/shims/env.ts:
--------------------------------------------------------------------------------
1 | export function loadEnvConfig() {}
2 |
--------------------------------------------------------------------------------
/examples/e2e/shared/sst-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .DS_Store
3 |
4 | output
5 | .open-next
6 | .wrangler
7 | .turbo
8 | dist
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "editor.formatOnSave": true,
3 | "cSpell.words": ["nextjs"]
4 | }
5 |
--------------------------------------------------------------------------------
/packages/cloudflare/src/cli/templates/shims/throw.ts:
--------------------------------------------------------------------------------
1 | throw "OpenNext shim";
2 | export default {};
3 |
--------------------------------------------------------------------------------
/examples/bugs/gh-119/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["next/core-web-vitals", "next/typescript"]
3 | }
4 |
--------------------------------------------------------------------------------
/examples/common/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "common",
3 | "private": true,
4 | "type": "module"
5 | }
6 |
--------------------------------------------------------------------------------
/examples/e2e/app-router/README.md:
--------------------------------------------------------------------------------
1 | # App Router
2 |
3 | This project uses the App Router exclusively...
4 |
--------------------------------------------------------------------------------
/examples/e2e/app-router/app/og/page.tsx:
--------------------------------------------------------------------------------
1 | export default function Page() {
2 | return
;
3 | }
4 |
--------------------------------------------------------------------------------
/examples/e2e/app-router/app/parallel/page.tsx:
--------------------------------------------------------------------------------
1 | export default function Page() {
2 | return null;
3 | }
4 |
--------------------------------------------------------------------------------
/examples/create-next-app/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["next/core-web-vitals", "next/typescript"]
3 | }
4 |
--------------------------------------------------------------------------------
/examples/e2e/app-pages-router/app/parallel/page.tsx:
--------------------------------------------------------------------------------
1 | export default function Page() {
2 | return null;
3 | }
4 |
--------------------------------------------------------------------------------
/examples/e2e/pages-router/README.md:
--------------------------------------------------------------------------------
1 | # Pages Router
2 |
3 | This project uses the Pages Router exclusively.
4 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # https://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | indent_style = tab
6 | end_of_line = lf
7 |
--------------------------------------------------------------------------------
/examples/e2e/app-router/app/albums/@modal/default.tsx:
--------------------------------------------------------------------------------
1 | export default function Default() {
2 | return null;
3 | }
4 |
--------------------------------------------------------------------------------
/examples/middleware/app/about/page.tsx:
--------------------------------------------------------------------------------
1 | export default function AboutPage() {
2 | return About
;
3 | }
4 |
--------------------------------------------------------------------------------
/examples/middleware/app/about2/page.tsx:
--------------------------------------------------------------------------------
1 | export default function About2Page() {
2 | return About 2
;
3 | }
4 |
--------------------------------------------------------------------------------
/create-cloudflare/next/.dev.vars:
--------------------------------------------------------------------------------
1 | # Load .env.development* files when running `wrangler dev`
2 | NEXTJS_ENV=development
3 |
--------------------------------------------------------------------------------
/create-cloudflare/next/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "files.associations": {
3 | "wrangler.json": "jsonc"
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/examples/e2e/app-pages-router/README.md:
--------------------------------------------------------------------------------
1 | # App Pages Router
2 |
3 | This project uses both the App and Pages router.
4 |
--------------------------------------------------------------------------------
/examples/e2e/app-pages-router/app/albums/@modal/default.tsx:
--------------------------------------------------------------------------------
1 | export default function Default() {
2 | return null;
3 | }
4 |
--------------------------------------------------------------------------------
/examples/middleware/app/another/page.tsx:
--------------------------------------------------------------------------------
1 | export default function AnotherPage() {
2 | return Another
;
3 | }
4 |
--------------------------------------------------------------------------------
/examples/middleware/app/rewrite/page.tsx:
--------------------------------------------------------------------------------
1 | export default function RewritePage() {
2 | return Rewrite
;
3 | }
4 |
--------------------------------------------------------------------------------
/examples/vercel-blog-starter/src/app/globals.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
--------------------------------------------------------------------------------
/examples/e2e/app-router/app/ssr/loading.tsx:
--------------------------------------------------------------------------------
1 | export default function Loading() {
2 | return Loading...
;
3 | }
4 |
--------------------------------------------------------------------------------
/examples/vercel-blog-starter/src/interfaces/author.ts:
--------------------------------------------------------------------------------
1 | export type Author = {
2 | name: string;
3 | picture: string;
4 | };
5 |
--------------------------------------------------------------------------------
/examples/e2e/app-pages-router/app/ssr/loading.tsx:
--------------------------------------------------------------------------------
1 | export default function Loading() {
2 | return Loading...
;
3 | }
4 |
--------------------------------------------------------------------------------
/examples/e2e/app-router/app/albums/[album]/page.tsx:
--------------------------------------------------------------------------------
1 | export default function ArtistPage() {
2 | return Artist
;
3 | }
4 |
--------------------------------------------------------------------------------
/examples/e2e/app-router/app/parallel/@a/a-page/page.tsx:
--------------------------------------------------------------------------------
1 | export default function APage() {
2 | return A Page
;
3 | }
4 |
--------------------------------------------------------------------------------
/examples/e2e/app-router/app/parallel/@b/b-page/page.tsx:
--------------------------------------------------------------------------------
1 | export default function BPage() {
2 | return B Page
;
3 | }
4 |
--------------------------------------------------------------------------------
/examples/ssg-app/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-cloudflare/HEAD/examples/ssg-app/app/favicon.ico
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | .next
2 | .wrangler
3 | pnpm-lock.yaml
4 | .vscode/setting.json
5 | test-fixtures
6 | test-snapshots
7 | playwright-report
--------------------------------------------------------------------------------
/examples/e2e/app-pages-router/app/albums/[album]/page.tsx:
--------------------------------------------------------------------------------
1 | export default function ArtistPage() {
2 | return Artist
;
3 | }
4 |
--------------------------------------------------------------------------------
/examples/e2e/app-pages-router/app/parallel/@a/a-page/page.tsx:
--------------------------------------------------------------------------------
1 | export default function APage() {
2 | return A Page
;
3 | }
4 |
--------------------------------------------------------------------------------
/examples/e2e/app-pages-router/app/parallel/@b/b-page/page.tsx:
--------------------------------------------------------------------------------
1 | export default function BPage() {
2 | return B Page
;
3 | }
4 |
--------------------------------------------------------------------------------
/examples/middleware/app/clerk/route.ts:
--------------------------------------------------------------------------------
1 | export async function POST(request: Request) {
2 | return new Response(`Hello clerk`);
3 | }
4 |
--------------------------------------------------------------------------------
/examples/prisma/src/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-cloudflare/HEAD/examples/prisma/src/app/favicon.ico
--------------------------------------------------------------------------------
/create-cloudflare/next/postcss.config.mjs:
--------------------------------------------------------------------------------
1 | const config = {
2 | plugins: ["@tailwindcss/postcss"],
3 | };
4 |
5 | export default config;
6 |
--------------------------------------------------------------------------------
/examples/bugs/gh-119/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-cloudflare/HEAD/examples/bugs/gh-119/app/favicon.ico
--------------------------------------------------------------------------------
/examples/bugs/gh-223/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-cloudflare/HEAD/examples/bugs/gh-223/app/favicon.ico
--------------------------------------------------------------------------------
/examples/e2e/app-router/app/revalidate-tag/nested/page.tsx:
--------------------------------------------------------------------------------
1 | export default async function Nested() {
2 | return Nested
;
3 | }
4 |
--------------------------------------------------------------------------------
/examples/e2e/app-router/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | };
7 |
--------------------------------------------------------------------------------
/examples/middleware/app/redirected/page.tsx:
--------------------------------------------------------------------------------
1 | export default function RedirectedPage() {
2 | return Redirected from /about
;
3 | }
4 |
--------------------------------------------------------------------------------
/examples/playground15/public/test.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-cloudflare/HEAD/examples/playground15/public/test.jpg
--------------------------------------------------------------------------------
/examples/bugs/gh-219/src/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-cloudflare/HEAD/examples/bugs/gh-219/src/app/favicon.ico
--------------------------------------------------------------------------------
/examples/e2e/app-pages-router/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | };
7 |
--------------------------------------------------------------------------------
/examples/middleware/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-cloudflare/HEAD/examples/middleware/public/favicon.ico
--------------------------------------------------------------------------------
/examples/playground15/data.js:
--------------------------------------------------------------------------------
1 | import styles from "./data.module.css";
2 |
3 | export const data = {
4 | now: Date.now(),
5 | styles,
6 | };
7 |
--------------------------------------------------------------------------------
/examples/playground15/public/tomine.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-cloudflare/HEAD/examples/playground15/public/tomine.webp
--------------------------------------------------------------------------------
/examples/vercel-blog-starter/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | };
7 |
--------------------------------------------------------------------------------
/examples/e2e/app-router/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-cloudflare/HEAD/examples/e2e/app-router/public/favicon.ico
--------------------------------------------------------------------------------
/examples/next-partial-prerendering/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | };
7 |
--------------------------------------------------------------------------------
/examples/ssg-app/worker-configuration.d.ts:
--------------------------------------------------------------------------------
1 | interface CloudflareEnv {
2 | APP_VERSION: "1.2.345";
3 | MY_SECRET: string;
4 | ASSETS: Fetcher;
5 | }
6 |
--------------------------------------------------------------------------------
/examples/bugs/gh-119/app/fonts/GeistVF.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-cloudflare/HEAD/examples/bugs/gh-119/app/fonts/GeistVF.woff
--------------------------------------------------------------------------------
/examples/create-next-app/src/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-cloudflare/HEAD/examples/create-next-app/src/app/favicon.ico
--------------------------------------------------------------------------------
/examples/e2e/experimental/src/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-cloudflare/HEAD/examples/e2e/experimental/src/app/favicon.ico
--------------------------------------------------------------------------------
/examples/e2e/pages-router/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-cloudflare/HEAD/examples/e2e/pages-router/public/favicon.ico
--------------------------------------------------------------------------------
/examples/middleware/open-next.config.ts:
--------------------------------------------------------------------------------
1 | import { defineCloudflareConfig } from "@opennextjs/cloudflare";
2 |
3 | export default defineCloudflareConfig();
4 |
--------------------------------------------------------------------------------
/examples/playground14/public/snipp/snipp.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-cloudflare/HEAD/examples/playground14/public/snipp/snipp.webp
--------------------------------------------------------------------------------
/examples/prisma/open-next.config.ts:
--------------------------------------------------------------------------------
1 | import { defineCloudflareConfig } from "@opennextjs/cloudflare";
2 |
3 | export default defineCloudflareConfig({});
4 |
--------------------------------------------------------------------------------
/examples/bugs/gh-119/app/fonts/GeistMonoVF.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-cloudflare/HEAD/examples/bugs/gh-119/app/fonts/GeistMonoVF.woff
--------------------------------------------------------------------------------
/examples/bugs/gh-119/open-next.config.ts:
--------------------------------------------------------------------------------
1 | import { defineCloudflareConfig } from "@opennextjs/cloudflare";
2 |
3 | export default defineCloudflareConfig();
4 |
--------------------------------------------------------------------------------
/examples/bugs/gh-219/open-next.config.ts:
--------------------------------------------------------------------------------
1 | import { defineCloudflareConfig } from "@opennextjs/cloudflare";
2 |
3 | export default defineCloudflareConfig();
4 |
--------------------------------------------------------------------------------
/examples/bugs/gh-223/open-next.config.ts:
--------------------------------------------------------------------------------
1 | import { defineCloudflareConfig } from "@opennextjs/cloudflare";
2 |
3 | export default defineCloudflareConfig();
4 |
--------------------------------------------------------------------------------
/examples/create-next-app/open-next.config.ts:
--------------------------------------------------------------------------------
1 | import { defineCloudflareConfig } from "@opennextjs/cloudflare";
2 |
3 | export default defineCloudflareConfig();
4 |
--------------------------------------------------------------------------------
/examples/e2e/app-router/app/redirect-destination/page.tsx:
--------------------------------------------------------------------------------
1 | export default function RedirectDestination() {
2 | return Redirect Destination
;
3 | }
4 |
--------------------------------------------------------------------------------
/examples/e2e/app-router/app/rewrite-destination/page.tsx:
--------------------------------------------------------------------------------
1 | export default function RewriteDestination() {
2 | return Rewritten Destination
;
3 | }
4 |
--------------------------------------------------------------------------------
/examples/next-partial-prerendering/types/review.d.ts:
--------------------------------------------------------------------------------
1 | export type Review = {
2 | id: string;
3 | name: string;
4 | rating: number;
5 | text: string;
6 | };
7 |
--------------------------------------------------------------------------------
/examples/overrides/d1-tag-next/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-cloudflare/HEAD/examples/overrides/d1-tag-next/app/favicon.ico
--------------------------------------------------------------------------------
/examples/overrides/kv-tag-next/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-cloudflare/HEAD/examples/overrides/kv-tag-next/app/favicon.ico
--------------------------------------------------------------------------------
/examples/overrides/memory-queue/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-cloudflare/HEAD/examples/overrides/memory-queue/app/favicon.ico
--------------------------------------------------------------------------------
/examples/playground14/app/page.js:
--------------------------------------------------------------------------------
1 | export default function Home() {
2 | return (
3 |
4 | Test misc Next features
5 |
6 | );
7 | }
8 |
--------------------------------------------------------------------------------
/examples/playground15/app/page.js:
--------------------------------------------------------------------------------
1 | export default function Home() {
2 | return (
3 |
4 | Test misc Next features
5 |
6 | );
7 | }
8 |
--------------------------------------------------------------------------------
/examples/prisma/e2e/playwright.config.ts:
--------------------------------------------------------------------------------
1 | import { configurePlaywright } from "../../common/config-e2e";
2 |
3 | export default configurePlaywright("prisma");
4 |
--------------------------------------------------------------------------------
/examples/bugs/gh-119/public/vercel.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/bugs/gh-219/public/vercel.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/e2e/app-pages-router/app/redirect-destination/page.tsx:
--------------------------------------------------------------------------------
1 | export default function RedirectDestination() {
2 | return Redirect Destination
;
3 | }
4 |
--------------------------------------------------------------------------------
/examples/e2e/app-pages-router/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-cloudflare/HEAD/examples/e2e/app-pages-router/public/favicon.ico
--------------------------------------------------------------------------------
/examples/e2e/app-router/public/static/frank.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-cloudflare/HEAD/examples/e2e/app-router/public/static/frank.webp
--------------------------------------------------------------------------------
/examples/e2e/experimental/README.md:
--------------------------------------------------------------------------------
1 | # Experimental
2 |
3 | This project is meant to test experimental features that are only available on canary builds of Next.js.
4 |
--------------------------------------------------------------------------------
/examples/e2e/pages-router/public/static/frank.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-cloudflare/HEAD/examples/e2e/pages-router/public/static/frank.webp
--------------------------------------------------------------------------------
/examples/next-partial-prerendering/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-cloudflare/HEAD/examples/next-partial-prerendering/app/favicon.ico
--------------------------------------------------------------------------------
/examples/ssg-app/e2e/playwright.config.ts:
--------------------------------------------------------------------------------
1 | import { configurePlaywright } from "../../common/config-e2e";
2 |
3 | export default configurePlaywright("ssg-app");
4 |
--------------------------------------------------------------------------------
/examples/bugs/gh-119/e2e/playwright.config.ts:
--------------------------------------------------------------------------------
1 | import { configurePlaywright } from "../../../common/config-e2e";
2 |
3 | export default configurePlaywright("gh-119");
4 |
--------------------------------------------------------------------------------
/examples/bugs/gh-219/e2e/playwright.config.ts:
--------------------------------------------------------------------------------
1 | import { configurePlaywright } from "../../../common/config-e2e";
2 |
3 | export default configurePlaywright("gh-219");
4 |
--------------------------------------------------------------------------------
/examples/bugs/gh-223/e2e/playwright.config.ts:
--------------------------------------------------------------------------------
1 | import { configurePlaywright } from "../../../common/config-e2e";
2 |
3 | export default configurePlaywright("gh-223");
4 |
--------------------------------------------------------------------------------
/examples/create-next-app/src/app/fonts/GeistVF.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-cloudflare/HEAD/examples/create-next-app/src/app/fonts/GeistVF.woff
--------------------------------------------------------------------------------
/examples/create-next-app/src/app/fonts/GeistMonoVF.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-cloudflare/HEAD/examples/create-next-app/src/app/fonts/GeistMonoVF.woff
--------------------------------------------------------------------------------
/examples/e2e/app-pages-router/public/static/frank.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-cloudflare/HEAD/examples/e2e/app-pages-router/public/static/frank.webp
--------------------------------------------------------------------------------
/examples/overrides/r2-incremental-cache/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-cloudflare/HEAD/examples/overrides/r2-incremental-cache/app/favicon.ico
--------------------------------------------------------------------------------
/examples/playground14/e2e/playwright.config.ts:
--------------------------------------------------------------------------------
1 | import { configurePlaywright } from "../../common/config-e2e";
2 |
3 | export default configurePlaywright("playground14");
4 |
--------------------------------------------------------------------------------
/examples/playground15/e2e/playwright.config.ts:
--------------------------------------------------------------------------------
1 | import { configurePlaywright } from "../../common/config-e2e";
2 |
3 | export default configurePlaywright("playground15");
4 |
--------------------------------------------------------------------------------
/examples/vercel-blog-starter/public/favicon/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-cloudflare/HEAD/examples/vercel-blog-starter/public/favicon/favicon.ico
--------------------------------------------------------------------------------
/packages/cloudflare/src/api/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./cloudflare-context.js";
2 | export { defineCloudflareConfig, getDeploymentId, type OpenNextConfig } from "./config.js";
3 |
--------------------------------------------------------------------------------
/examples/e2e/experimental/e2e/playwright.config.ts:
--------------------------------------------------------------------------------
1 | import { configurePlaywright } from "../../../common/config-e2e";
2 |
3 | export default configurePlaywright("experimental");
4 |
--------------------------------------------------------------------------------
/examples/next-partial-prerendering/app/twitter-image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-cloudflare/HEAD/examples/next-partial-prerendering/app/twitter-image.png
--------------------------------------------------------------------------------
/examples/vercel-blog-starter/src/app/_components/section-separator.tsx:
--------------------------------------------------------------------------------
1 | export function SectionSeparator() {
2 | return
;
3 | }
4 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------
1 | blank_issues_enabled: true
2 | contact_links:
3 | - name: Support
4 | url: https://discord.gg/opennextjs
5 | about: "Join us on Discord!"
6 |
--------------------------------------------------------------------------------
/examples/next-partial-prerendering/app/opengraph-image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-cloudflare/HEAD/examples/next-partial-prerendering/app/opengraph-image.png
--------------------------------------------------------------------------------
/examples/prisma/prisma.config.ts:
--------------------------------------------------------------------------------
1 | import type { PrismaConfig } from "prisma";
2 |
3 | export default {
4 | earlyAccess: true,
5 | schema: "./schema.prisma",
6 | } satisfies PrismaConfig;
7 |
--------------------------------------------------------------------------------
/examples/vercel-blog-starter/public/favicon/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-cloudflare/HEAD/examples/vercel-blog-starter/public/favicon/favicon-16x16.png
--------------------------------------------------------------------------------
/examples/vercel-blog-starter/public/favicon/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-cloudflare/HEAD/examples/vercel-blog-starter/public/favicon/favicon-32x32.png
--------------------------------------------------------------------------------
/examples/vercel-blog-starter/public/favicon/mstile-150x150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-cloudflare/HEAD/examples/vercel-blog-starter/public/favicon/mstile-150x150.png
--------------------------------------------------------------------------------
/examples/e2e/app-router/public/static/corporate_holiday_card.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-cloudflare/HEAD/examples/e2e/app-router/public/static/corporate_holiday_card.jpg
--------------------------------------------------------------------------------
/examples/middleware/e2e/playwright.config.ts:
--------------------------------------------------------------------------------
1 | import { configurePlaywright } from "../../common/config-e2e";
2 |
3 | export default configurePlaywright("middleware", { multipleBrowsers: true });
4 |
--------------------------------------------------------------------------------
/examples/vercel-blog-starter/public/assets/blog/authors/jj.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-cloudflare/HEAD/examples/vercel-blog-starter/public/assets/blog/authors/jj.jpeg
--------------------------------------------------------------------------------
/examples/vercel-blog-starter/public/assets/blog/authors/joe.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-cloudflare/HEAD/examples/vercel-blog-starter/public/assets/blog/authors/joe.jpeg
--------------------------------------------------------------------------------
/examples/vercel-blog-starter/public/assets/blog/authors/tim.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-cloudflare/HEAD/examples/vercel-blog-starter/public/assets/blog/authors/tim.jpeg
--------------------------------------------------------------------------------
/examples/vercel-blog-starter/public/assets/blog/preview/cover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-cloudflare/HEAD/examples/vercel-blog-starter/public/assets/blog/preview/cover.jpg
--------------------------------------------------------------------------------
/examples/vercel-blog-starter/public/favicon/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-cloudflare/HEAD/examples/vercel-blog-starter/public/favicon/apple-touch-icon.png
--------------------------------------------------------------------------------
/examples/bugs/gh-119/postcss.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import('postcss-load-config').Config} */
2 | const config = {
3 | plugins: {
4 | tailwindcss: {},
5 | },
6 | };
7 |
8 | export default config;
9 |
--------------------------------------------------------------------------------
/examples/bugs/gh-219/postcss.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import('postcss-load-config').Config} */
2 | const config = {
3 | plugins: {
4 | tailwindcss: {},
5 | },
6 | };
7 |
8 | export default config;
9 |
--------------------------------------------------------------------------------
/examples/bugs/gh-223/postcss.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import('postcss-load-config').Config} */
2 | const config = {
3 | plugins: {
4 | tailwindcss: {},
5 | },
6 | };
7 |
8 | export default config;
9 |
--------------------------------------------------------------------------------
/examples/e2e/app-router/e2e/playwright.config.ts:
--------------------------------------------------------------------------------
1 | import { configurePlaywright } from "../../../common/config-e2e";
2 |
3 | export default configurePlaywright("app-router", { useTurbopack: false });
4 |
--------------------------------------------------------------------------------
/examples/next-partial-prerendering/e2e/playwright.config.ts:
--------------------------------------------------------------------------------
1 | import { configurePlaywright } from '../../common/config-e2e';
2 |
3 | export default configurePlaywright('next-partial-prerendering');
4 |
--------------------------------------------------------------------------------
/examples/overrides/static-assets-incremental-cache/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-cloudflare/HEAD/examples/overrides/static-assets-incremental-cache/app/favicon.ico
--------------------------------------------------------------------------------
/examples/create-next-app/e2e/playwright.config.ts:
--------------------------------------------------------------------------------
1 | import { configurePlaywright } from "../../common/config-e2e";
2 |
3 | export default configurePlaywright("create-next-app", { multipleBrowsers: true });
4 |
--------------------------------------------------------------------------------
/examples/create-next-app/postcss.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import('postcss-load-config').Config} */
2 | const config = {
3 | plugins: {
4 | tailwindcss: {},
5 | },
6 | };
7 |
8 | export default config;
9 |
--------------------------------------------------------------------------------
/examples/e2e/app-pages-router/public/static/corporate_holiday_card.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-cloudflare/HEAD/examples/e2e/app-pages-router/public/static/corporate_holiday_card.jpg
--------------------------------------------------------------------------------
/examples/e2e/app-router/app/methods/get/redirect/route.ts:
--------------------------------------------------------------------------------
1 | import { redirect } from "next/navigation";
2 |
3 | export async function GET(request: Request) {
4 | redirect("https://nextjs.org/");
5 | }
6 |
--------------------------------------------------------------------------------
/examples/e2e/pages-router/e2e/playwright.config.ts:
--------------------------------------------------------------------------------
1 | import { configurePlaywright } from "../../../common/config-e2e";
2 |
3 | export default configurePlaywright("pages-router", { useTurbopack: false });
4 |
--------------------------------------------------------------------------------
/examples/vercel-blog-starter/public/assets/blog/hello-world/cover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-cloudflare/HEAD/examples/vercel-blog-starter/public/assets/blog/hello-world/cover.jpg
--------------------------------------------------------------------------------
/examples/vercel-blog-starter/public/favicon/android-chrome-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-cloudflare/HEAD/examples/vercel-blog-starter/public/favicon/android-chrome-192x192.png
--------------------------------------------------------------------------------
/examples/vercel-blog-starter/public/favicon/android-chrome-512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-cloudflare/HEAD/examples/vercel-blog-starter/public/favicon/android-chrome-512x512.png
--------------------------------------------------------------------------------
/packages/cloudflare/src/cli/build/utils/normalize-path.ts:
--------------------------------------------------------------------------------
1 | import { posix, sep } from "node:path";
2 |
3 | export function normalizePath(path: string) {
4 | return path.replaceAll(sep, posix.sep);
5 | }
6 |
--------------------------------------------------------------------------------
/examples/e2e/app-router/e2e/playwright.turbopack.config.ts:
--------------------------------------------------------------------------------
1 | import { configurePlaywright } from "../../../common/config-e2e";
2 |
3 | export default configurePlaywright("app-router", { useTurbopack: true });
4 |
--------------------------------------------------------------------------------
/examples/e2e/experimental/src/app/api/revalidate/route.ts:
--------------------------------------------------------------------------------
1 | import { revalidateTag } from "next/cache";
2 |
3 | export function GET() {
4 | revalidateTag("fullyTagged");
5 | return new Response("DONE");
6 | }
7 |
--------------------------------------------------------------------------------
/examples/e2e/app-pages-router/e2e/playwright.config.ts:
--------------------------------------------------------------------------------
1 | import { configurePlaywright } from "../../../common/config-e2e";
2 |
3 | export default configurePlaywright("app-pages-router", { useTurbopack: false });
4 |
--------------------------------------------------------------------------------
/examples/e2e/pages-router/e2e/playwright.turbopack.config.ts:
--------------------------------------------------------------------------------
1 | import { configurePlaywright } from "../../../common/config-e2e";
2 |
3 | export default configurePlaywright("pages-router", { useTurbopack: true });
4 |
--------------------------------------------------------------------------------
/examples/next-partial-prerendering/public/nextjs-icon-light-background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-cloudflare/HEAD/examples/next-partial-prerendering/public/nextjs-icon-light-background.png
--------------------------------------------------------------------------------
/examples/next-partial-prerendering/public/patrick-OIFgeLnjwrM-unsplash.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-cloudflare/HEAD/examples/next-partial-prerendering/public/patrick-OIFgeLnjwrM-unsplash.jpg
--------------------------------------------------------------------------------
/examples/vercel-blog-starter/public/assets/blog/dynamic-routing/cover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-cloudflare/HEAD/examples/vercel-blog-starter/public/assets/blog/dynamic-routing/cover.jpg
--------------------------------------------------------------------------------
/examples/e2e/app-pages-router/e2e/playwright.turbopack.config.ts:
--------------------------------------------------------------------------------
1 | import { configurePlaywright } from "../../../common/config-e2e";
2 |
3 | export default configurePlaywright("app-pages-router", { useTurbopack: true });
4 |
--------------------------------------------------------------------------------
/examples/e2e/app-router/app/api/client/route.ts:
--------------------------------------------------------------------------------
1 | import { NextResponse } from "next/server";
2 |
3 | export async function GET(request: Request) {
4 | return NextResponse.json({
5 | hello: "client",
6 | });
7 | }
8 |
--------------------------------------------------------------------------------
/examples/e2e/app-router/app/api/host/route.ts:
--------------------------------------------------------------------------------
1 | import { NextResponse } from "next/server";
2 |
3 | export async function GET(request: Request) {
4 | return NextResponse.json({
5 | url: request.url,
6 | });
7 | }
8 |
--------------------------------------------------------------------------------
/examples/e2e/utils.ts:
--------------------------------------------------------------------------------
1 | import { createHash } from "node:crypto";
2 |
3 | export function validateMd5(data: Buffer, expectedHash: string) {
4 | return createHash("md5").update(data).digest("hex") === expectedHash;
5 | }
6 |
--------------------------------------------------------------------------------
/examples/next-partial-prerendering/public/eniko-kis-KsLPTsYaqIQ-unsplash.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-cloudflare/HEAD/examples/next-partial-prerendering/public/eniko-kis-KsLPTsYaqIQ-unsplash.jpg
--------------------------------------------------------------------------------
/examples/e2e/app-pages-router/app/api/client/route.ts:
--------------------------------------------------------------------------------
1 | import { NextResponse } from "next/server";
2 |
3 | export async function GET(request: Request) {
4 | return NextResponse.json({
5 | hello: "client",
6 | });
7 | }
8 |
--------------------------------------------------------------------------------
/examples/e2e/app-pages-router/app/api/host/route.ts:
--------------------------------------------------------------------------------
1 | import { NextResponse } from "next/server";
2 |
3 | export async function GET(request: Request) {
4 | return NextResponse.json({
5 | url: request.url,
6 | });
7 | }
8 |
--------------------------------------------------------------------------------
/examples/next-partial-prerendering/public/prince-akachi-LWkFHEGpleE-unsplash.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-cloudflare/HEAD/examples/next-partial-prerendering/public/prince-akachi-LWkFHEGpleE-unsplash.jpg
--------------------------------------------------------------------------------
/examples/next-partial-prerendering/public/yoann-siloine-_T4w3JDm6ug-unsplash.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-cloudflare/HEAD/examples/next-partial-prerendering/public/yoann-siloine-_T4w3JDm6ug-unsplash.jpg
--------------------------------------------------------------------------------
/examples/prisma/e2e/playwright.dev.config.ts:
--------------------------------------------------------------------------------
1 | import { configurePlaywright } from "../../common/config-e2e";
2 |
3 | export default configurePlaywright("prisma", {
4 | isCI: !!process.env.CI,
5 | isWorker: false,
6 | });
7 |
--------------------------------------------------------------------------------
/examples/next-partial-prerendering/public/guillaume-coupy-6HuoHgK7FN8-unsplash.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-cloudflare/HEAD/examples/next-partial-prerendering/public/guillaume-coupy-6HuoHgK7FN8-unsplash.jpg
--------------------------------------------------------------------------------
/examples/playground15/worker-configuration.d.ts:
--------------------------------------------------------------------------------
1 | // Generated by Wrangler by running `wrangler types --env-interface CloudflareEnv`
2 |
3 | interface CloudflareEnv {
4 | hello: "Hello World from the cloudflare context!";
5 | }
6 |
--------------------------------------------------------------------------------
/examples/bugs/gh-223/next.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | typescript: { ignoreBuildErrors: true },
4 | eslint: { ignoreDuringBuilds: true },
5 | };
6 |
7 | export default nextConfig;
8 |
--------------------------------------------------------------------------------
/examples/middleware/e2e/playwright.dev.config.ts:
--------------------------------------------------------------------------------
1 | import { configurePlaywright } from "../../common/config-e2e";
2 |
3 | export default configurePlaywright("middleware", {
4 | isCI: !!process.env.CI,
5 | isWorker: false,
6 | });
7 |
--------------------------------------------------------------------------------
/examples/next-partial-prerendering/public/alexander-andrews-brAkTCdnhW8-unsplash.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/opennextjs/opennextjs-cloudflare/HEAD/examples/next-partial-prerendering/public/alexander-andrews-brAkTCdnhW8-unsplash.jpg
--------------------------------------------------------------------------------
/examples/playground14/e2e/playwright.dev.config.ts:
--------------------------------------------------------------------------------
1 | import { configurePlaywright } from "../../common/config-e2e";
2 |
3 | export default configurePlaywright("playground14", {
4 | isCI: !!process.env.CI,
5 | isWorker: false,
6 | });
7 |
--------------------------------------------------------------------------------
/examples/playground15/e2e/playwright.dev.config.ts:
--------------------------------------------------------------------------------
1 | import { configurePlaywright } from "../../common/config-e2e";
2 |
3 | export default configurePlaywright("playground15", {
4 | isCI: !!process.env.CI,
5 | isWorker: false,
6 | });
7 |
--------------------------------------------------------------------------------
/examples/e2e/app-pages-router/app/ssg/page.tsx:
--------------------------------------------------------------------------------
1 | export const dynamic = "force-static";
2 |
3 | export default function Page() {
4 | return (
5 |
6 | This is a static page
7 |
8 | );
9 | }
10 |
--------------------------------------------------------------------------------
/examples/e2e/app-router/app/server-actions/page.tsx:
--------------------------------------------------------------------------------
1 | import Client from "./client";
2 |
3 | export default function Page() {
4 | return (
5 |
6 |
Server Actions
7 |
8 |
9 | );
10 | }
11 |
--------------------------------------------------------------------------------
/examples/e2e/experimental/src/components/static.tsx:
--------------------------------------------------------------------------------
1 | export function StaticComponent() {
2 | return (
3 |
4 |
Static Component
5 |
This is a static component that does not change.
6 |
7 | );
8 | }
9 |
--------------------------------------------------------------------------------
/examples/e2e/pages-router/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | tailwindcss: {
4 | content: ["./src/**/*.{js,ts,jsx,tsx,mdx}", "../../examples/shared/**/*.{jsx,tsx}"],
5 | },
6 | autoprefixer: {},
7 | },
8 | };
9 |
--------------------------------------------------------------------------------
/examples/e2e/app-pages-router/app/server-actions/page.tsx:
--------------------------------------------------------------------------------
1 | import Client from "./client";
2 |
3 | export default function Page() {
4 | return (
5 |
6 |
Server Actions
7 |
8 |
9 | );
10 | }
11 |
--------------------------------------------------------------------------------
/examples/e2e/app-router/app/revalidate-tag/page.tsx:
--------------------------------------------------------------------------------
1 | async function getTime() {
2 | return new Date().toISOString();
3 | }
4 |
5 | export default async function ISR() {
6 | const time = getTime();
7 | return Time: {time}
;
8 | }
9 |
--------------------------------------------------------------------------------
/examples/e2e/app-router/open-next.turbopack.config.ts:
--------------------------------------------------------------------------------
1 | import config from "./open-next.config.js";
2 |
3 | export default {
4 | ...config,
5 | // Override the build command to use Turbopack
6 | buildCommand: "next build --turbopack",
7 | };
8 |
--------------------------------------------------------------------------------
/examples/vercel-blog-starter/next.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | typescript: { ignoreBuildErrors: true },
4 | eslint: { ignoreDuringBuilds: true },
5 | };
6 |
7 | export default nextConfig;
8 |
--------------------------------------------------------------------------------
/examples/bugs/gh-119/next.config.ts:
--------------------------------------------------------------------------------
1 | import type { NextConfig } from "next";
2 |
3 | const nextConfig: NextConfig = {
4 | typescript: { ignoreBuildErrors: true },
5 | eslint: { ignoreDuringBuilds: true },
6 | };
7 |
8 | export default nextConfig;
9 |
--------------------------------------------------------------------------------
/examples/bugs/gh-219/next.config.ts:
--------------------------------------------------------------------------------
1 | import type { NextConfig } from "next";
2 |
3 | const nextConfig: NextConfig = {
4 | typescript: { ignoreBuildErrors: true },
5 | eslint: { ignoreDuringBuilds: true },
6 | };
7 |
8 | export default nextConfig;
9 |
--------------------------------------------------------------------------------
/examples/e2e/app-pages-router/open-next.turbopack.config.ts:
--------------------------------------------------------------------------------
1 | import config from "./open-next.config.js";
2 |
3 | export default {
4 | ...config,
5 | // Override the build command to use Turbopack
6 | buildCommand: "next build --turbopack",
7 | };
8 |
--------------------------------------------------------------------------------
/examples/e2e/app-pages-router/pages/_app.tsx:
--------------------------------------------------------------------------------
1 | import "@/styles/globals.css";
2 |
3 | import type { AppProps } from "next/app";
4 |
5 | export default function App({ Component, pageProps }: AppProps) {
6 | return ;
7 | }
8 |
--------------------------------------------------------------------------------
/examples/e2e/app-router/app/cookies/page.tsx:
--------------------------------------------------------------------------------
1 | import { cookies } from "next/headers";
2 |
3 | export default async function Page() {
4 | const foo = (await cookies()).get("foo")?.value;
5 |
6 | return {foo}
;
7 | }
8 |
--------------------------------------------------------------------------------
/examples/e2e/app-router/app/methods/get/dynamic-segments/[slug]/route.ts:
--------------------------------------------------------------------------------
1 | export async function GET(request: Request, { params }: { params: Promise<{ slug: string }> }) {
2 | const { slug } = await params;
3 | return Response.json({ slug });
4 | }
5 |
--------------------------------------------------------------------------------
/examples/e2e/pages-router/open-next.turbopack.config.ts:
--------------------------------------------------------------------------------
1 | import config from "./open-next.config.js";
2 |
3 | export default {
4 | ...config,
5 | // Override the build command to use Turbopack
6 | buildCommand: "next build --turbopack",
7 | };
8 |
--------------------------------------------------------------------------------
/examples/e2e/pages-router/src/pages/_app.tsx:
--------------------------------------------------------------------------------
1 | import "@/styles/globals.css";
2 |
3 | import type { AppProps } from "next/app";
4 |
5 | export default function App({ Component, pageProps }: AppProps) {
6 | return ;
7 | }
8 |
--------------------------------------------------------------------------------
/examples/playground14/app/api/request/route.ts:
--------------------------------------------------------------------------------
1 | import { NextRequest } from "next/server";
2 |
3 | export const GET = (request: NextRequest) => {
4 | return new Response(JSON.stringify({ nextUrl: request.nextUrl.href, url: request.url }));
5 | };
6 |
--------------------------------------------------------------------------------
/examples/playground15/app/api/request/route.ts:
--------------------------------------------------------------------------------
1 | import { NextRequest } from "next/server";
2 |
3 | export const GET = (request: NextRequest) => {
4 | return new Response(JSON.stringify({ nextUrl: request.nextUrl.href, url: request.url }));
5 | };
6 |
--------------------------------------------------------------------------------
/create-cloudflare/next/public/_headers:
--------------------------------------------------------------------------------
1 | # https://developers.cloudflare.com/workers/static-assets/headers
2 | # https://opennext.js.org/cloudflare/caching#static-assets-caching
3 | /_next/static/*
4 | Cache-Control: public,max-age=31536000,immutable
5 |
--------------------------------------------------------------------------------
/examples/e2e/pages-router/src/pages/api/query.ts:
--------------------------------------------------------------------------------
1 | import type { NextApiRequest, NextApiResponse } from "next";
2 |
3 | export default function handler(req: NextApiRequest, res: NextApiResponse) {
4 | res.status(200).json({ query: req.query });
5 | }
6 |
--------------------------------------------------------------------------------
/examples/e2e/pages-router/src/pages/fallback-intercepted/static.tsx:
--------------------------------------------------------------------------------
1 | export default function Page() {
2 | return (
3 |
4 |
Static Fallback Page
5 |
This is a fully static page.
6 |
7 | );
8 | }
9 |
--------------------------------------------------------------------------------
/examples/overrides/d1-tag-next/e2e/playwright.config.ts:
--------------------------------------------------------------------------------
1 | import { configurePlaywright } from "../../../common/config-e2e";
2 |
3 | // Here we don't want to run the tests in parallel
4 | export default configurePlaywright("d1-tag-next", { parallel: false });
5 |
--------------------------------------------------------------------------------
/examples/overrides/kv-tag-next/e2e/playwright.config.ts:
--------------------------------------------------------------------------------
1 | import { configurePlaywright } from "../../../common/config-e2e";
2 |
3 | // Here we don't want to run the tests in parallel
4 | export default configurePlaywright("kv-tag-next", { parallel: false });
5 |
--------------------------------------------------------------------------------
/examples/next-partial-prerendering/components/product-best-seller.tsx:
--------------------------------------------------------------------------------
1 | export const ProductBestSeller = () => {
2 | return (
3 |
4 | Best Seller
5 |
6 | );
7 | };
8 |
--------------------------------------------------------------------------------
/examples/e2e/app-pages-router/app/ssr/layout.tsx:
--------------------------------------------------------------------------------
1 | import type { PropsWithChildren } from "react";
2 |
3 | export default function Layout({ children }: PropsWithChildren) {
4 | return (
5 |
6 |
SSR
7 | {children}
8 |
9 | );
10 | }
11 |
--------------------------------------------------------------------------------
/examples/e2e/app-router/app/isr/page.tsx:
--------------------------------------------------------------------------------
1 | async function getTime() {
2 | return new Date().toISOString();
3 | }
4 |
5 | export const revalidate = 10;
6 | export default async function ISR() {
7 | const time = getTime();
8 | return Time: {time}
;
9 | }
10 |
--------------------------------------------------------------------------------
/examples/e2e/pages-router/src/pages/api/dynamic/precedence/index.ts:
--------------------------------------------------------------------------------
1 | import type { NextApiRequest, NextApiResponse } from "next";
2 |
3 | export default function handler(req: NextApiRequest, res: NextApiResponse) {
4 | res.status(200).json({ precedence: "true" });
5 | }
6 |
--------------------------------------------------------------------------------
/examples/playground15/app/api/signal/revalidate/route.ts:
--------------------------------------------------------------------------------
1 | import { revalidatePath } from "next/cache";
2 |
3 | export const dynamic = "force-dynamic";
4 |
5 | export async function GET() {
6 | revalidatePath("/signal/");
7 |
8 | return new Response("ok");
9 | }
10 |
--------------------------------------------------------------------------------
/examples/ssg-app/app/globals.css:
--------------------------------------------------------------------------------
1 | html,
2 | body {
3 | max-width: 100vw;
4 | overflow-x: hidden;
5 | height: 100vh;
6 | display: flex;
7 | flex-direction: column;
8 | }
9 |
10 | footer {
11 | padding: 1rem;
12 | display: flex;
13 | justify-content: end;
14 | }
15 |
--------------------------------------------------------------------------------
/examples/e2e/app-pages-router/app/isr/page.tsx:
--------------------------------------------------------------------------------
1 | async function getTime() {
2 | return new Date().toISOString();
3 | }
4 |
5 | export const revalidate = 10;
6 | export default async function ISR() {
7 | const time = getTime();
8 | return Time: {time}
;
9 | }
10 |
--------------------------------------------------------------------------------
/examples/e2e/app-router/app/api/revalidate-path/route.ts:
--------------------------------------------------------------------------------
1 | import { revalidatePath } from "next/cache";
2 |
3 | export const dynamic = "force-dynamic";
4 |
5 | export async function GET() {
6 | revalidatePath("/revalidate-path");
7 |
8 | return new Response("ok");
9 | }
10 |
--------------------------------------------------------------------------------
/examples/e2e/pages-router/src/pages/api/dynamic/[slug].ts:
--------------------------------------------------------------------------------
1 | import type { NextApiRequest, NextApiResponse } from "next";
2 |
3 | export default function handler(req: NextApiRequest, res: NextApiResponse) {
4 | const { slug } = req.query;
5 | res.status(200).json({ slug });
6 | }
7 |
--------------------------------------------------------------------------------
/examples/e2e/pages-router/src/pages/api/dynamic/catch-all-optional/[[...slug]].ts:
--------------------------------------------------------------------------------
1 | import type { NextApiRequest, NextApiResponse } from "next";
2 |
3 | export default function handler(req: NextApiRequest, res: NextApiResponse) {
4 | res.status(200).json({ optional: "true" });
5 | }
6 |
--------------------------------------------------------------------------------
/examples/e2e/app-router/app/albums/layout.tsx:
--------------------------------------------------------------------------------
1 | import type { ReactNode } from "react";
2 |
3 | export default function Layout({ children, modal }: { children: ReactNode; modal: ReactNode }) {
4 | return (
5 |
6 | {children}
7 | {modal}
8 |
9 | );
10 | }
11 |
--------------------------------------------------------------------------------
/examples/e2e/app-router/app/api/revalidate-tag/route.ts:
--------------------------------------------------------------------------------
1 | import { revalidateTag } from "next/cache";
2 |
3 | export const dynamic = "force-dynamic";
4 |
5 | export async function GET() {
6 | revalidateTag("revalidate", { expire: 0 });
7 |
8 | return new Response("ok");
9 | }
10 |
--------------------------------------------------------------------------------
/examples/e2e/app-pages-router/app/albums/layout.tsx:
--------------------------------------------------------------------------------
1 | import type { ReactNode } from "react";
2 |
3 | export default function Layout({ children, modal }: { children: ReactNode; modal: ReactNode }) {
4 | return (
5 |
6 | {children}
7 | {modal}
8 |
9 | );
10 | }
11 |
--------------------------------------------------------------------------------
/examples/e2e/app-router/app/parallel/@a/page.tsx:
--------------------------------------------------------------------------------
1 | import Link from "next/link";
2 |
3 | export default function A() {
4 | return (
5 |
6 |
Parallel Route A
7 | Go to a-page
8 |
9 | );
10 | }
11 |
--------------------------------------------------------------------------------
/examples/overrides/d1-tag-next/app/globals.css:
--------------------------------------------------------------------------------
1 | html,
2 | body {
3 | max-width: 100vw;
4 | overflow-x: hidden;
5 | height: 100vh;
6 | display: flex;
7 | flex-direction: column;
8 | }
9 |
10 | footer {
11 | padding: 1rem;
12 | display: flex;
13 | justify-content: end;
14 | }
15 |
--------------------------------------------------------------------------------
/examples/overrides/kv-tag-next/app/globals.css:
--------------------------------------------------------------------------------
1 | html,
2 | body {
3 | max-width: 100vw;
4 | overflow-x: hidden;
5 | height: 100vh;
6 | display: flex;
7 | flex-direction: column;
8 | }
9 |
10 | footer {
11 | padding: 1rem;
12 | display: flex;
13 | justify-content: end;
14 | }
15 |
--------------------------------------------------------------------------------
/examples/overrides/memory-queue/app/globals.css:
--------------------------------------------------------------------------------
1 | html,
2 | body {
3 | max-width: 100vw;
4 | overflow-x: hidden;
5 | height: 100vh;
6 | display: flex;
7 | flex-direction: column;
8 | }
9 |
10 | footer {
11 | padding: 1rem;
12 | display: flex;
13 | justify-content: end;
14 | }
15 |
--------------------------------------------------------------------------------
/examples/vercel-blog-starter/src/app/_components/container.tsx:
--------------------------------------------------------------------------------
1 | type Props = {
2 | children?: React.ReactNode;
3 | };
4 |
5 | const Container = ({ children }: Props) => {
6 | return {children}
;
7 | };
8 |
9 | export default Container;
10 |
--------------------------------------------------------------------------------
/examples/e2e/app-router/app/methods/get/revalidate/route.ts:
--------------------------------------------------------------------------------
1 | export const revalidate = 5;
2 |
3 | async function getTime() {
4 | return new Date().toISOString();
5 | }
6 |
7 | export async function GET() {
8 | const time = await getTime();
9 | return Response.json({ time });
10 | }
11 |
--------------------------------------------------------------------------------
/examples/playground15/app/image/page.tsx:
--------------------------------------------------------------------------------
1 | import Image from "next/image";
2 |
3 | import tomineImg from "../../public/tomine.webp";
4 |
5 | export default function Page() {
6 | return (
7 |
8 |
9 |
10 | );
11 | }
12 |
--------------------------------------------------------------------------------
/examples/vercel-blog-starter/src/lib/markdownToHtml.ts:
--------------------------------------------------------------------------------
1 | import { remark } from "remark";
2 | import html from "remark-html";
3 |
4 | export default async function markdownToHtml(markdown: string) {
5 | const result = await remark().use(html).process(markdown);
6 | return result.toString();
7 | }
8 |
--------------------------------------------------------------------------------
/examples/e2e/app-pages-router/app/parallel/@a/page.tsx:
--------------------------------------------------------------------------------
1 | import Link from "next/link";
2 |
3 | export default function A() {
4 | return (
5 |
6 |
Parallel Route A
7 | Go to a-page
8 |
9 | );
10 | }
11 |
--------------------------------------------------------------------------------
/examples/e2e/app-router/app/methods/get/static/route.ts:
--------------------------------------------------------------------------------
1 | export const dynamic = "force-static";
2 |
3 | async function getTime() {
4 | return new Date().toISOString();
5 | }
6 |
7 | export async function GET() {
8 | const time = await getTime();
9 | return Response.json({ time });
10 | }
11 |
--------------------------------------------------------------------------------
/examples/e2e/app-router/app/parallel/@b/page.tsx:
--------------------------------------------------------------------------------
1 | import Link from "next/link";
2 |
3 | export default function B() {
4 | return (
5 |
6 |
Parallel Route B
7 |
8 | Go to b-page
9 |
10 | );
11 | }
12 |
--------------------------------------------------------------------------------
/examples/overrides/r2-incremental-cache/app/globals.css:
--------------------------------------------------------------------------------
1 | html,
2 | body {
3 | max-width: 100vw;
4 | overflow-x: hidden;
5 | height: 100vh;
6 | display: flex;
7 | flex-direction: column;
8 | }
9 |
10 | footer {
11 | padding: 1rem;
12 | display: flex;
13 | justify-content: end;
14 | }
15 |
--------------------------------------------------------------------------------
/examples/e2e/app-pages-router/app/parallel/@b/page.tsx:
--------------------------------------------------------------------------------
1 | import Link from "next/link";
2 |
3 | export default function B() {
4 | return (
5 |
6 |
Parallel Route B
7 |
8 | Go to b-page
9 |
10 | );
11 | }
12 |
--------------------------------------------------------------------------------
/examples/next-partial-prerendering/app/not-found.tsx:
--------------------------------------------------------------------------------
1 | export default function NotFound() {
2 | return (
3 |
4 |
Not Found
5 |
Could not find requested resource
6 |
7 | );
8 | }
9 |
--------------------------------------------------------------------------------
/examples/next-partial-prerendering/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {
3 | typescript: { ignoreBuildErrors: true },
4 | eslint: { ignoreDuringBuilds: true },
5 | experimental: {
6 | ppr: true,
7 | },
8 | };
9 |
10 | module.exports = nextConfig;
11 |
--------------------------------------------------------------------------------
/examples/playground14/pages/api/pages.ts:
--------------------------------------------------------------------------------
1 | import type { NextApiRequest, NextApiResponse } from "next";
2 |
3 | type Data = {
4 | hello: string;
5 | };
6 |
7 | export default function handler(req: NextApiRequest, res: NextApiResponse) {
8 | res.status(200).json({ hello: "world" });
9 | }
10 |
--------------------------------------------------------------------------------
/examples/overrides/static-assets-incremental-cache/app/globals.css:
--------------------------------------------------------------------------------
1 | html,
2 | body {
3 | max-width: 100vw;
4 | overflow-x: hidden;
5 | height: 100vh;
6 | display: flex;
7 | flex-direction: column;
8 | }
9 |
10 | footer {
11 | padding: 1rem;
12 | display: flex;
13 | justify-content: end;
14 | }
15 |
--------------------------------------------------------------------------------
/examples/overrides/d1-tag-next/app/action.ts:
--------------------------------------------------------------------------------
1 | "use server";
2 |
3 | import { revalidatePath, revalidateTag } from "next/cache";
4 |
5 | export async function revalidateTagAction() {
6 | revalidateTag("date");
7 | }
8 |
9 | export async function revalidatePathAction() {
10 | revalidatePath("/");
11 | }
12 |
--------------------------------------------------------------------------------
/examples/overrides/kv-tag-next/app/action.ts:
--------------------------------------------------------------------------------
1 | "use server";
2 |
3 | import { revalidatePath, revalidateTag } from "next/cache";
4 |
5 | export async function revalidateTagAction() {
6 | revalidateTag("date");
7 | }
8 |
9 | export async function revalidatePathAction() {
10 | revalidatePath("/");
11 | }
12 |
--------------------------------------------------------------------------------
/examples/playground14/app/layout.js:
--------------------------------------------------------------------------------
1 | export const metadata = {
2 | title: "API hello-world",
3 | description: "a simple api hello-world app",
4 | };
5 |
6 | export default function RootLayout({ children }) {
7 | return (
8 |
9 | {children}
10 |
11 | );
12 | }
13 |
--------------------------------------------------------------------------------
/examples/playground15/app/layout.js:
--------------------------------------------------------------------------------
1 | export const metadata = {
2 | title: "API hello-world",
3 | description: "a simple api hello-world app",
4 | };
5 |
6 | export default function RootLayout({ children }) {
7 | return (
8 |
9 | {children}
10 |
11 | );
12 | }
13 |
--------------------------------------------------------------------------------
/examples/e2e/app-pages-router/app/image-optimization/page.tsx:
--------------------------------------------------------------------------------
1 | import Image from "next/image";
2 |
3 | export default function ImageOptimization() {
4 | return (
5 |
6 |
7 |
8 | );
9 | }
10 |
--------------------------------------------------------------------------------
/examples/e2e/app-pages-router/pages/_document.tsx:
--------------------------------------------------------------------------------
1 | import { Head, Html, Main, NextScript } from "next/document";
2 |
3 | export default function Document() {
4 | return (
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | );
13 | }
14 |
--------------------------------------------------------------------------------
/examples/e2e/pages-router/src/pages/_document.tsx:
--------------------------------------------------------------------------------
1 | import { Head, Html, Main, NextScript } from "next/document";
2 |
3 | export default function Document() {
4 | return (
5 |
6 |
8 |
9 |
10 |
11 |
12 | );
13 | }
14 |
--------------------------------------------------------------------------------
/examples/next-partial-prerendering/components/cart-count.tsx:
--------------------------------------------------------------------------------
1 | 'use client';
2 |
3 | import { useCartCount } from '#/components/cart-count-context';
4 |
5 | export function CartCount({ initialCartCount }: { initialCartCount: number }) {
6 | const [count] = useCartCount(initialCartCount);
7 | return {count};
8 | }
9 |
--------------------------------------------------------------------------------
/examples/overrides/memory-queue/e2e/playwright.config.ts:
--------------------------------------------------------------------------------
1 | import { configurePlaywright } from "../../../common/config-e2e";
2 |
3 | // Here we don't want to run the tests in parallel
4 | export default configurePlaywright("memory-queue", {
5 | isCI: !!process.env.CI,
6 | parallel: false,
7 | multipleBrowsers: false,
8 | });
9 |
--------------------------------------------------------------------------------
/packages/cloudflare/src/cli/build/utils/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./copy-package-cli-files.js";
2 | export * from "./create-config-files.js";
3 | export * from "./ensure-cf-config.js";
4 | export * from "./extract-project-env-vars.js";
5 | export * from "./needs-experimental-react.js";
6 | export * from "./normalize-path.js";
7 |
--------------------------------------------------------------------------------
/examples/e2e/app-router/app/headers/page.tsx:
--------------------------------------------------------------------------------
1 | import { headers } from "next/headers";
2 |
3 | export default async function Headers() {
4 | const middlewareHeader = (await headers()).get("request-header");
5 | return (
6 |
7 |
Headers
8 |
{middlewareHeader}
9 |
10 | );
11 | }
12 |
--------------------------------------------------------------------------------
/examples/bugs/gh-119/e2e/base.spec.ts:
--------------------------------------------------------------------------------
1 | import { test, expect } from "@playwright/test";
2 |
3 | test.describe("bugs/gh-119", () => {
4 | test("the index page of the application shows the Next.js logo", async ({ page }) => {
5 | await page.goto("/");
6 | await expect(page.getByAltText("Next.js logo")).toBeVisible();
7 | });
8 | });
9 |
--------------------------------------------------------------------------------
/examples/bugs/gh-219/e2e/base.spec.ts:
--------------------------------------------------------------------------------
1 | import { test, expect } from "@playwright/test";
2 |
3 | test.describe("bugs/gh-219", () => {
4 | test("the index page of the application shows the Next.js logo", async ({ page }) => {
5 | await page.goto("/");
6 | await expect(page.getByAltText("Next.js logo")).toBeVisible();
7 | });
8 | });
9 |
--------------------------------------------------------------------------------
/examples/overrides/static-assets-incremental-cache/app/action.ts:
--------------------------------------------------------------------------------
1 | "use server";
2 |
3 | import { revalidatePath, revalidateTag } from "next/cache";
4 |
5 | export async function revalidateTagAction() {
6 | revalidateTag("date");
7 | }
8 |
9 | export async function revalidatePathAction() {
10 | revalidatePath("/");
11 | }
12 |
--------------------------------------------------------------------------------
/examples/overrides/static-assets-incremental-cache/e2e/playwright.config.ts:
--------------------------------------------------------------------------------
1 | import { configurePlaywright } from "../../../common/config-e2e";
2 |
3 | // Here we don't want to run the tests in parallel
4 | export default configurePlaywright("static-assets-incremental-cache", {
5 | isCI: !!process.env.CI,
6 | parallel: false,
7 | });
8 |
--------------------------------------------------------------------------------
/examples/overrides/d1-tag-next/next.config.ts:
--------------------------------------------------------------------------------
1 | import type { NextConfig } from "next";
2 | import { initOpenNextCloudflareForDev } from "@opennextjs/cloudflare";
3 |
4 | initOpenNextCloudflareForDev();
5 |
6 | const nextConfig: NextConfig = {
7 | typescript: { ignoreBuildErrors: true },
8 | };
9 |
10 | export default nextConfig;
11 |
--------------------------------------------------------------------------------
/examples/overrides/kv-tag-next/next.config.ts:
--------------------------------------------------------------------------------
1 | import type { NextConfig } from "next";
2 | import { initOpenNextCloudflareForDev } from "@opennextjs/cloudflare";
3 |
4 | initOpenNextCloudflareForDev();
5 |
6 | const nextConfig: NextConfig = {
7 | typescript: { ignoreBuildErrors: true },
8 | };
9 |
10 | export default nextConfig;
11 |
--------------------------------------------------------------------------------
/examples/overrides/memory-queue/next.config.ts:
--------------------------------------------------------------------------------
1 | import type { NextConfig } from "next";
2 | import { initOpenNextCloudflareForDev } from "@opennextjs/cloudflare";
3 |
4 | initOpenNextCloudflareForDev();
5 |
6 | const nextConfig: NextConfig = {
7 | typescript: { ignoreBuildErrors: true },
8 | };
9 |
10 | export default nextConfig;
11 |
--------------------------------------------------------------------------------
/examples/overrides/r2-incremental-cache/e2e/playwright.config.ts:
--------------------------------------------------------------------------------
1 | import { configurePlaywright } from "../../../common/config-e2e";
2 |
3 | // Here we don't want to run the tests in parallel
4 | export default configurePlaywright("r2-incremental-cache", {
5 | isCI: !!process.env.CI,
6 | parallel: false,
7 | multipleBrowsers: false,
8 | });
9 |
--------------------------------------------------------------------------------
/examples/playground15/app/api/instrumentation/route.ts:
--------------------------------------------------------------------------------
1 | import { NextResponse } from "next/server";
2 |
3 | export function GET() {
4 | return NextResponse.json({
5 | "nodejs-instrumentation-setup": globalThis["__NODEJS_INSTRUMENTATION_SETUP"],
6 | "edge-instrumentation-setup": globalThis["__EDGE_INSTRUMENTATION_SETUP"],
7 | });
8 | }
9 |
--------------------------------------------------------------------------------
/examples/ssg-app/open-next.config.ts:
--------------------------------------------------------------------------------
1 | import { defineCloudflareConfig } from "@opennextjs/cloudflare";
2 | import staticAssetsIncrementalCache from "@opennextjs/cloudflare/overrides/incremental-cache/static-assets-incremental-cache";
3 |
4 | export default defineCloudflareConfig({
5 | incrementalCache: staticAssetsIncrementalCache,
6 | });
7 |
--------------------------------------------------------------------------------
/examples/create-next-app/e2e/base.spec.ts:
--------------------------------------------------------------------------------
1 | import { test, expect } from "@playwright/test";
2 |
3 | test.describe("create-next-app", () => {
4 | test("the index page of the application shows the Next.js logo", async ({ page }) => {
5 | await page.goto("/");
6 | await expect(page.getByAltText("Next.js logo")).toBeVisible();
7 | });
8 | });
9 |
--------------------------------------------------------------------------------
/examples/e2e/app-router/app/api/auth/[...better-auth]/route.ts:
--------------------------------------------------------------------------------
1 | import { NextResponse } from "next/server";
2 |
3 | export async function GET(_req: Request, { params }: { params: Promise<{ "better-auth": string[] }> }) {
4 | const { "better-auth": slugs } = await params;
5 |
6 | return NextResponse.json({
7 | slugs,
8 | });
9 | }
10 |
--------------------------------------------------------------------------------
/examples/prisma/schema.prisma:
--------------------------------------------------------------------------------
1 | generator client {
2 | provider = "prisma-client-js"
3 | previewFeatures = ["driverAdapters"]
4 | }
5 |
6 | datasource db {
7 | provider = "sqlite"
8 | url = env("NOT_USED")
9 | }
10 |
11 | model users {
12 | id Int @id @default(autoincrement())
13 | email String @unique
14 | name String?
15 | }
--------------------------------------------------------------------------------
/examples/bugs/gh-223/e2e/base.spec.ts:
--------------------------------------------------------------------------------
1 | import { test, expect } from "@playwright/test";
2 |
3 | test.describe("bugs/gh-223", () => {
4 | test("api route", async ({ page }) => {
5 | const res = await page.request.get("/api/image");
6 | expect(res.status()).toEqual(200);
7 | expect((await res.json()).image).toEqual("");
8 | });
9 | });
10 |
--------------------------------------------------------------------------------
/examples/overrides/r2-incremental-cache/next.config.ts:
--------------------------------------------------------------------------------
1 | import type { NextConfig } from "next";
2 | import { initOpenNextCloudflareForDev } from "@opennextjs/cloudflare";
3 |
4 | initOpenNextCloudflareForDev();
5 |
6 | const nextConfig: NextConfig = {
7 | typescript: { ignoreBuildErrors: true },
8 | };
9 |
10 | export default nextConfig;
11 |
--------------------------------------------------------------------------------
/examples/playground14/open-next.config.ts:
--------------------------------------------------------------------------------
1 | import { defineCloudflareConfig } from "@opennextjs/cloudflare";
2 | import kvIncrementalCache from "@opennextjs/cloudflare/overrides/incremental-cache/kv-incremental-cache";
3 |
4 | export default defineCloudflareConfig({
5 | incrementalCache: kvIncrementalCache,
6 | enableCacheInterception: true,
7 | });
8 |
--------------------------------------------------------------------------------
/examples/playground15/app/signal/page.tsx:
--------------------------------------------------------------------------------
1 | import SSE from "./_components/sse";
2 |
3 | export const dynamic = "force-static";
4 |
5 | export default function Page() {
6 | const date = new Date().toISOString();
7 |
8 | return (
9 |
10 | {date}
11 |
12 |
13 |
14 | );
15 | }
16 |
--------------------------------------------------------------------------------
/examples/vercel-blog-starter/open-next.config.ts:
--------------------------------------------------------------------------------
1 | import { defineCloudflareConfig } from "@opennextjs/cloudflare";
2 | import staticAssetsIncrementalCache from "@opennextjs/cloudflare/overrides/incremental-cache/static-assets-incremental-cache";
3 |
4 | export default defineCloudflareConfig({
5 | incrementalCache: staticAssetsIncrementalCache,
6 | });
7 |
--------------------------------------------------------------------------------
/examples/e2e/app-pages-router/e2e/skip_trailing.test.ts:
--------------------------------------------------------------------------------
1 | import { expect, test } from "@playwright/test";
2 |
3 | test("skipTrailingSlashRedirect redirect", async ({ page }) => {
4 | const response = await page.goto("/ssr");
5 |
6 | expect(response?.request().redirectedFrom()).toBeNull();
7 | expect(response?.request().url()).toMatch(/\/ssr$/);
8 | });
9 |
--------------------------------------------------------------------------------
/examples/vercel-blog-starter/public/favicon/browserconfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | #000000
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/examples/vercel-blog-starter/src/interfaces/post.ts:
--------------------------------------------------------------------------------
1 | import { type Author } from "./author";
2 |
3 | export type Post = {
4 | slug: string;
5 | title: string;
6 | date: string;
7 | coverImage: string;
8 | author: Author;
9 | excerpt: string;
10 | ogImage: {
11 | url: string;
12 | };
13 | content: string;
14 | preview?: boolean;
15 | };
16 |
--------------------------------------------------------------------------------
/benchmarking/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@opennextjs-cloudflare/benchmarking",
3 | "private": true,
4 | "type": "module",
5 | "devDependencies": {
6 | "tsx": "catalog:",
7 | "@tsconfig/strictest": "catalog:",
8 | "@types/node": "catalog:",
9 | "ora": "^8.1.0"
10 | },
11 | "scripts": {
12 | "benchmark": "tsx src/index.ts"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/examples/e2e/app-router/app/config-redirect/dest/page.tsx:
--------------------------------------------------------------------------------
1 | export default async function Page({
2 | searchParams,
3 | }: {
4 | searchParams: Promise<{ [key: string]: string | string[] | undefined }>;
5 | }) {
6 | const q = (await searchParams).q;
7 |
8 | return (
9 | <>
10 | q: {q}
11 | >
12 | );
13 | }
14 |
--------------------------------------------------------------------------------
/examples/e2e/app-router/app/image-optimization/page.tsx:
--------------------------------------------------------------------------------
1 | import Image from "next/image";
2 |
3 | export default function ImageOptimization() {
4 | return (
5 |
6 |
12 |
13 | );
14 | }
15 |
--------------------------------------------------------------------------------
/examples/middleware/next.config.mjs:
--------------------------------------------------------------------------------
1 | import { initOpenNextCloudflareForDev } from "@opennextjs/cloudflare";
2 |
3 | initOpenNextCloudflareForDev();
4 |
5 | /** @type {import('next').NextConfig} */
6 | const nextConfig = {
7 | typescript: { ignoreBuildErrors: true },
8 | eslint: { ignoreDuringBuilds: true },
9 | };
10 |
11 | export default nextConfig;
12 |
--------------------------------------------------------------------------------
/examples/next-partial-prerendering/open-next.config.ts:
--------------------------------------------------------------------------------
1 | import { defineCloudflareConfig } from '@opennextjs/cloudflare/config';
2 | import staticAssetsIncrementalCache from '@opennextjs/cloudflare/overrides/incremental-cache/static-assets-incremental-cache';
3 |
4 | export default defineCloudflareConfig({
5 | incrementalCache: staticAssetsIncrementalCache,
6 | });
7 |
--------------------------------------------------------------------------------
/examples/create-next-app/next.config.mjs:
--------------------------------------------------------------------------------
1 | import { initOpenNextCloudflareForDev } from "@opennextjs/cloudflare";
2 |
3 | initOpenNextCloudflareForDev();
4 |
5 | /** @type {import('next').NextConfig} */
6 | const nextConfig = {
7 | typescript: { ignoreBuildErrors: true },
8 | eslint: { ignoreDuringBuilds: true },
9 | };
10 |
11 | export default nextConfig;
12 |
--------------------------------------------------------------------------------
/examples/e2e/app-router/app/albums/@modal/(.)[album]/page.tsx:
--------------------------------------------------------------------------------
1 | import Modal from "@example/shared/components/Modal";
2 |
3 | type Props = {
4 | params: Promise<{
5 | artist: string;
6 | }>;
7 | };
8 | export default async function ArtistPage(props: Props) {
9 | const params = await props.params;
10 | return Artists {params.artist};
11 | }
12 |
--------------------------------------------------------------------------------
/examples/e2e/app-router/app/ssr/layout.tsx:
--------------------------------------------------------------------------------
1 | import type { PropsWithChildren } from "react";
2 |
3 | export default function Layout({ children }: PropsWithChildren) {
4 | return (
5 |
6 |
SSR
7 | {/* 16 kb seems necessary here to prevent any buffering*/}
8 | {/* */}
9 | {children}
10 |
11 | );
12 | }
13 |
--------------------------------------------------------------------------------
/examples/playground14/app/api/env/route.ts:
--------------------------------------------------------------------------------
1 | // This test relies on using `.dev.vars` to set the environment to `development`
2 | // However `next build` is not passed an environment, so we do not want to cache
3 | // the output.
4 | export const dynamic = "force-dynamic";
5 |
6 | export async function GET() {
7 | return new Response(JSON.stringify(process.env));
8 | }
9 |
--------------------------------------------------------------------------------
/examples/prisma/populate.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE IF NOT EXISTS users (
2 | id INTEGER PRIMARY KEY AUTOINCREMENT,
3 | name TEXT NOT NULL,
4 | email TEXT NOT NULL,
5 | UNIQUE (email) ON CONFLICT REPLACE
6 | );
7 |
8 | INSERT INTO users (name, email) VALUES
9 | ('Alice', 'alice@example.com'),
10 | ('Bob', 'bob@example.com'),
11 | ('Carol', 'carol@example.com');
--------------------------------------------------------------------------------
/examples/ssg-app/next.config.ts:
--------------------------------------------------------------------------------
1 | import type { NextConfig } from "next";
2 | import { initOpenNextCloudflareForDev } from "@opennextjs/cloudflare";
3 |
4 | initOpenNextCloudflareForDev();
5 |
6 | const nextConfig: NextConfig = {
7 | typescript: { ignoreBuildErrors: true },
8 | eslint: { ignoreDuringBuilds: true },
9 | };
10 |
11 | export default nextConfig;
12 |
--------------------------------------------------------------------------------
/examples/e2e/app-pages-router/app/albums/@modal/(.)[album]/page.tsx:
--------------------------------------------------------------------------------
1 | import Modal from "@example/shared/components/Modal";
2 |
3 | type Props = {
4 | params: Promise<{
5 | artist: string;
6 | }>;
7 | };
8 | export default async function ArtistPage(props: Props) {
9 | const params = await props.params;
10 | return Artists {params.artist};
11 | }
12 |
--------------------------------------------------------------------------------
/examples/overrides/static-assets-incremental-cache/open-next.config.ts:
--------------------------------------------------------------------------------
1 | import { defineCloudflareConfig } from "@opennextjs/cloudflare";
2 | import staticAssetsIncrementalCache from "@opennextjs/cloudflare/overrides/incremental-cache/static-assets-incremental-cache";
3 |
4 | export default defineCloudflareConfig({
5 | incrementalCache: staticAssetsIncrementalCache,
6 | });
7 |
--------------------------------------------------------------------------------
/examples/e2e/app-router/app/albums/page.tsx:
--------------------------------------------------------------------------------
1 | import { getAlbums } from "@example/shared/api";
2 | import Album from "@example/shared/components/Album";
3 |
4 | export default async function AlbumPage() {
5 | const albums = await getAlbums();
6 | return (
7 |
8 | {albums.map((album) => (
9 |
10 | ))}
11 |
12 | );
13 | }
14 |
--------------------------------------------------------------------------------
/examples/e2e/app-router/e2e/host.test.ts:
--------------------------------------------------------------------------------
1 | import { expect, test } from "@playwright/test";
2 |
3 | /**
4 | * Tests that the request.url is correct
5 | */
6 | test("Request.url is host", async ({ baseURL, page }) => {
7 | await page.goto("/api/host");
8 |
9 | const el = page.getByText(`{"url":"${baseURL}/api/host"}`);
10 | await expect(el).toBeVisible();
11 | });
12 |
--------------------------------------------------------------------------------
/examples/ssg-app/app/page.module.css:
--------------------------------------------------------------------------------
1 | .page {
2 | display: grid;
3 | grid-template-rows: 20px 1fr 20px;
4 | align-items: center;
5 | justify-items: center;
6 | flex: 1;
7 | border: 3px solid gray;
8 | margin: 1rem;
9 | margin-block-end: 0;
10 | }
11 |
12 | .main {
13 | display: flex;
14 | flex-direction: column;
15 | gap: 32px;
16 | grid-row-start: 2;
17 | }
18 |
--------------------------------------------------------------------------------
/examples/vercel-blog-starter/src/lib/constants.ts:
--------------------------------------------------------------------------------
1 | export const EXAMPLE_PATH = "blog-starter";
2 | export const CMS_NAME = "Markdown";
3 | export const HOME_OG_IMAGE_URL =
4 | "https://og-image.vercel.app/Next.js%20Blog%20Starter%20Example.png?theme=light&md=1&fontSize=100px&images=https%3A%2F%2Fassets.vercel.com%2Fimage%2Fupload%2Ffront%2Fassets%2Fdesign%2Fnextjs-black-logo.svg";
5 |
--------------------------------------------------------------------------------
/examples/bugs/gh-119/wrangler.jsonc:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "node_modules/wrangler/config-schema.json",
3 | "main": ".open-next/worker.js",
4 | "name": "gh-119",
5 | "compatibility_date": "2024-12-30",
6 | "compatibility_flags": ["nodejs_compat", "global_fetch_strictly_public"],
7 | "assets": {
8 | "directory": ".open-next/assets",
9 | "binding": "ASSETS"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/examples/bugs/gh-219/wrangler.jsonc:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "node_modules/wrangler/config-schema.json",
3 | "main": ".open-next/worker.js",
4 | "name": "gh-219",
5 | "compatibility_date": "2024-12-30",
6 | "compatibility_flags": ["nodejs_compat", "global_fetch_strictly_public"],
7 | "assets": {
8 | "directory": ".open-next/assets",
9 | "binding": "ASSETS"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/examples/bugs/gh-223/wrangler.jsonc:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "node_modules/wrangler/config-schema.json",
3 | "main": ".open-next/worker.js",
4 | "name": "gh-219",
5 | "compatibility_date": "2024-12-30",
6 | "compatibility_flags": ["nodejs_compat", "global_fetch_strictly_public"],
7 | "assets": {
8 | "directory": ".open-next/assets",
9 | "binding": "ASSETS"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/examples/common/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "lib": ["esnext"],
4 | "allowJs": true,
5 | "skipLibCheck": true,
6 | "strict": false,
7 | "noEmit": true,
8 | "incremental": true,
9 | "module": "esnext",
10 | "esModuleInterop": true,
11 | "moduleResolution": "node",
12 | "resolveJsonModule": true,
13 | "isolatedModules": true
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/examples/e2e/app-pages-router/e2e/host.test.ts:
--------------------------------------------------------------------------------
1 | import { expect, test } from "@playwright/test";
2 |
3 | /**
4 | * Tests that the request.url is correct
5 | */
6 | test("Request.url is host", async ({ baseURL, page }) => {
7 | await page.goto("/api/host");
8 |
9 | const el = page.getByText(`{"url":"${baseURL}/api/host"}`);
10 | await expect(el).toBeVisible();
11 | });
12 |
--------------------------------------------------------------------------------
/examples/e2e/app-pages-router/next.config.ts:
--------------------------------------------------------------------------------
1 | import type { NextConfig } from "next";
2 |
3 | const nextConfig: NextConfig = {
4 | poweredByHeader: false,
5 | cleanDistDir: true,
6 | output: "standalone",
7 | typescript: {
8 | ignoreBuildErrors: true,
9 | },
10 | trailingSlash: true,
11 | skipTrailingSlashRedirect: true,
12 | };
13 |
14 | export default nextConfig;
15 |
--------------------------------------------------------------------------------
/packages/cloudflare/env.d.ts:
--------------------------------------------------------------------------------
1 | declare global {
2 | namespace NodeJS {
3 | interface ProcessEnv {
4 | __NEXT_PRIVATE_STANDALONE_CONFIG?: string;
5 | SKIP_NEXT_APP_BUILD?: string;
6 | SKIP_WRANGLER_CONFIG_CHECK?: string;
7 | NEXT_PRIVATE_DEBUG_CACHE?: string;
8 | OPEN_NEXT_ORIGIN: string;
9 | NODE_ENV?: string;
10 | }
11 | }
12 | }
13 |
14 | export {};
15 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "printWidth": 110,
3 | "singleQuote": false,
4 | "semi": true,
5 | "useTabs": true,
6 | "trailingComma": "es5",
7 | "overrides": [
8 | {
9 | "// comment": "wrangler doesn't seem to accept wrangler.jsonc with trailing commas",
10 | "files": ["**/wrangler.jsonc"],
11 | "options": {
12 | "trailingComma": "none"
13 | }
14 | }
15 | ]
16 | }
17 |
--------------------------------------------------------------------------------
/examples/e2e/app-pages-router/app/albums/page.tsx:
--------------------------------------------------------------------------------
1 | import { getAlbums } from "@example/shared/api";
2 | import Album from "@example/shared/components/Album";
3 |
4 | export default async function AlbumPage() {
5 | const albums = await getAlbums();
6 | return (
7 |
8 | {albums.map((album) => (
9 |
10 | ))}
11 |
12 | );
13 | }
14 |
--------------------------------------------------------------------------------
/examples/e2e/experimental/src/app/use-cache/layout.tsx:
--------------------------------------------------------------------------------
1 | import { Suspense } from "react";
2 |
3 | export default function Layout({
4 | children,
5 | }: Readonly<{
6 | // For some reason using ReactNode here causes a type error
7 | children: any;
8 | }>) {
9 | return (
10 |
11 | Loading...}>{children}
12 |
13 | );
14 | }
15 |
--------------------------------------------------------------------------------
/examples/prisma/src/lib/db.ts:
--------------------------------------------------------------------------------
1 | import { PrismaClient } from "@prisma/client";
2 | import { PrismaD1 } from "@prisma/adapter-d1";
3 | import { getCloudflareContext } from "@opennextjs/cloudflare";
4 |
5 | export const getDb = () => {
6 | const { env } = getCloudflareContext();
7 | const adapter = new PrismaD1(env.DB);
8 | return new PrismaClient({
9 | adapter,
10 | });
11 | };
12 |
--------------------------------------------------------------------------------
/examples/create-next-app/wrangler.jsonc:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "node_modules/wrangler/config-schema.json",
3 | "main": ".open-next/worker.js",
4 | "name": "create-next-app",
5 | "compatibility_date": "2024-12-30",
6 | "compatibility_flags": ["nodejs_compat", "global_fetch_strictly_public"],
7 | "assets": {
8 | "directory": ".open-next/assets",
9 | "binding": "ASSETS"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/examples/e2e/app-pages-router/pages/api/hello.ts:
--------------------------------------------------------------------------------
1 | // Next.js API route support: https://nextjs.org/docs/api-routes/introduction
2 | import type { NextApiRequest, NextApiResponse } from "next";
3 |
4 | type Data = {
5 | hello: string;
6 | };
7 |
8 | export default function handler(req: NextApiRequest, res: NextApiResponse) {
9 | res.status(200).json({ hello: "world" });
10 | }
11 |
--------------------------------------------------------------------------------
/examples/overrides/d1-tag-next/app/page.module.css:
--------------------------------------------------------------------------------
1 | .page {
2 | display: grid;
3 | grid-template-rows: 20px 1fr 20px;
4 | align-items: center;
5 | justify-items: center;
6 | flex: 1;
7 | border: 3px solid gray;
8 | margin: 1rem;
9 | margin-block-end: 0;
10 | }
11 |
12 | .main {
13 | display: flex;
14 | flex-direction: column;
15 | gap: 32px;
16 | grid-row-start: 2;
17 | }
18 |
--------------------------------------------------------------------------------
/examples/overrides/kv-tag-next/app/page.module.css:
--------------------------------------------------------------------------------
1 | .page {
2 | display: grid;
3 | grid-template-rows: 20px 1fr 20px;
4 | align-items: center;
5 | justify-items: center;
6 | flex: 1;
7 | border: 3px solid gray;
8 | margin: 1rem;
9 | margin-block-end: 0;
10 | }
11 |
12 | .main {
13 | display: flex;
14 | flex-direction: column;
15 | gap: 32px;
16 | grid-row-start: 2;
17 | }
18 |
--------------------------------------------------------------------------------
/examples/overrides/memory-queue/app/page.module.css:
--------------------------------------------------------------------------------
1 | .page {
2 | display: grid;
3 | grid-template-rows: 20px 1fr 20px;
4 | align-items: center;
5 | justify-items: center;
6 | flex: 1;
7 | border: 3px solid gray;
8 | margin: 1rem;
9 | margin-block-end: 0;
10 | }
11 |
12 | .main {
13 | display: flex;
14 | flex-direction: column;
15 | gap: 32px;
16 | grid-row-start: 2;
17 | }
18 |
--------------------------------------------------------------------------------
/examples/e2e/pages-router/src/pages/api/dynamic/catch-all/[...slug].ts:
--------------------------------------------------------------------------------
1 | import type { NextApiRequest, NextApiResponse } from "next";
2 |
3 | export default function handler(req: NextApiRequest, res: NextApiResponse) {
4 | const { slug } = req.query;
5 | if (!Array.isArray(slug)) {
6 | return res.status(500).json({ error: "Invalid" });
7 | }
8 | res.status(200).json({ slug });
9 | }
10 |
--------------------------------------------------------------------------------
/examples/playground14/app/api/buildid/route.ts:
--------------------------------------------------------------------------------
1 | // Use headers to force a dynamic response
2 | import { headers } from "next/headers";
3 |
4 | export async function GET() {
5 | const nextConfig = process.env.__NEXT_PRIVATE_STANDALONE_CONFIG
6 | ? JSON.parse(process.env.__NEXT_PRIVATE_STANDALONE_CONFIG)
7 | : undefined;
8 | return Response.json({ nextConfig, headers: headers() });
9 | }
10 |
--------------------------------------------------------------------------------
/examples/playground14/app/api/instrumentation/route.ts:
--------------------------------------------------------------------------------
1 | import { NextResponse } from "next/server";
2 |
3 | export const dynamic = "force-dynamic";
4 |
5 | export function GET() {
6 | return NextResponse.json({
7 | "nodejs-instrumentation-setup": globalThis["__NODEJS_INSTRUMENTATION_SETUP"],
8 | "edge-instrumentation-setup": globalThis["__EDGE_INSTRUMENTATION_SETUP"],
9 | });
10 | }
11 |
--------------------------------------------------------------------------------
/examples/e2e/experimental/src/app/page.tsx:
--------------------------------------------------------------------------------
1 | import Link from "next/link";
2 | import styles from "./page.module.css";
3 |
4 | export default function Home() {
5 | return (
6 |
7 |
8 |
9 | Incremental PPR
10 |
11 |
12 |
13 | );
14 | }
15 |
--------------------------------------------------------------------------------
/examples/overrides/r2-incremental-cache/app/page.module.css:
--------------------------------------------------------------------------------
1 | .page {
2 | display: grid;
3 | grid-template-rows: 20px 1fr 20px;
4 | align-items: center;
5 | justify-items: center;
6 | flex: 1;
7 | border: 3px solid gray;
8 | margin: 1rem;
9 | margin-block-end: 0;
10 | }
11 |
12 | .main {
13 | display: flex;
14 | flex-direction: column;
15 | gap: 32px;
16 | grid-row-start: 2;
17 | }
18 |
--------------------------------------------------------------------------------
/examples/overrides/static-assets-incremental-cache/next.config.ts:
--------------------------------------------------------------------------------
1 | import type { NextConfig } from "next";
2 | import { initOpenNextCloudflareForDev } from "@opennextjs/cloudflare";
3 |
4 | initOpenNextCloudflareForDev();
5 |
6 | const nextConfig: NextConfig = {
7 | typescript: { ignoreBuildErrors: true },
8 | eslint: { ignoreDuringBuilds: true },
9 | };
10 |
11 | export default nextConfig;
12 |
--------------------------------------------------------------------------------
/examples/vercel-blog-starter/src/app/_components/date-formatter.tsx:
--------------------------------------------------------------------------------
1 | import { parseISO, format } from "date-fns";
2 |
3 | type Props = {
4 | dateString: string;
5 | };
6 |
7 | const DateFormatter = ({ dateString }: Props) => {
8 | const date = parseISO(dateString);
9 | return ;
10 | };
11 |
12 | export default DateFormatter;
13 |
--------------------------------------------------------------------------------
/examples/vercel-blog-starter/src/app/_components/markdown-styles.module.css:
--------------------------------------------------------------------------------
1 | .markdown {
2 | @apply text-lg leading-relaxed;
3 | }
4 |
5 | .markdown p,
6 | .markdown ul,
7 | .markdown ol,
8 | .markdown blockquote {
9 | @apply my-6;
10 | }
11 |
12 | .markdown h2 {
13 | @apply text-3xl mt-12 mb-4 leading-snug;
14 | }
15 |
16 | .markdown h3 {
17 | @apply text-2xl mt-8 mb-4 leading-snug;
18 | }
19 |
--------------------------------------------------------------------------------
/packages/cloudflare/templates/open-next.config.ts:
--------------------------------------------------------------------------------
1 | // default open-next.config.ts file created by @opennextjs/cloudflare
2 | import { defineCloudflareConfig } from "@opennextjs/cloudflare/config";
3 | import r2IncrementalCache from "@opennextjs/cloudflare/overrides/incremental-cache/r2-incremental-cache";
4 |
5 | export default defineCloudflareConfig({
6 | incrementalCache: r2IncrementalCache,
7 | });
8 |
--------------------------------------------------------------------------------
/examples/playground15/app/api/buildid/route.ts:
--------------------------------------------------------------------------------
1 | // Use headers to force a dynamic response
2 | import { headers } from "next/headers";
3 |
4 | export async function GET() {
5 | const nextConfig = process.env.__NEXT_PRIVATE_STANDALONE_CONFIG
6 | ? JSON.parse(process.env.__NEXT_PRIVATE_STANDALONE_CONFIG)
7 | : undefined;
8 | return Response.json({ nextConfig, headers: await headers() });
9 | }
10 |
--------------------------------------------------------------------------------
/examples/bugs/gh-119/public/window.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/bugs/gh-219/public/window.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/overrides/static-assets-incremental-cache/app/page.module.css:
--------------------------------------------------------------------------------
1 | .page {
2 | display: grid;
3 | grid-template-rows: 20px 1fr 20px;
4 | align-items: center;
5 | justify-items: center;
6 | flex: 1;
7 | border: 3px solid gray;
8 | margin: 1rem;
9 | margin-block-end: 0;
10 | }
11 |
12 | .main {
13 | display: flex;
14 | flex-direction: column;
15 | gap: 32px;
16 | grid-row-start: 2;
17 | }
18 |
--------------------------------------------------------------------------------
/examples/vercel-blog-starter/wrangler.jsonc:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "node_modules/wrangler/config-schema.json",
3 | "main": ".open-next/worker.js",
4 | "name": "vercel-blog-starter-on-workers",
5 | "compatibility_date": "2024-12-30",
6 | "compatibility_flags": ["nodejs_compat", "global_fetch_strictly_public"],
7 | "assets": {
8 | "directory": ".open-next/assets",
9 | "binding": "ASSETS"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/create-cloudflare/next/public/window.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/bugs/gh-119/public/file.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/bugs/gh-219/public/file.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/next-partial-prerendering/wrangler.jsonc:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "node_modules/wrangler/config-schema.json",
3 | "main": ".open-next/worker.js",
4 | "name": "next-partial-prerendering",
5 | "compatibility_date": "2024-12-30",
6 | "compatibility_flags": ["nodejs_compat", "global_fetch_strictly_public"],
7 | "assets": {
8 | "directory": ".open-next/assets",
9 | "binding": "ASSETS",
10 | },
11 | }
12 |
--------------------------------------------------------------------------------
/create-cloudflare/next/public/file.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/e2e/pages-router/open-next.config.ts:
--------------------------------------------------------------------------------
1 | import { defineCloudflareConfig } from "@opennextjs/cloudflare";
2 | import r2IncrementalCache from "@opennextjs/cloudflare/overrides/incremental-cache/r2-incremental-cache";
3 | import memoryQueue from "@opennextjs/cloudflare/overrides/queue/memory-queue";
4 |
5 | export default defineCloudflareConfig({
6 | incrementalCache: r2IncrementalCache,
7 | queue: memoryQueue,
8 | });
9 |
--------------------------------------------------------------------------------
/examples/vercel-blog-starter/src/app/_components/header.tsx:
--------------------------------------------------------------------------------
1 | import Link from "next/link";
2 |
3 | const Header = () => {
4 | return (
5 |
6 |
7 | Blog
8 |
9 | .
10 |
11 | );
12 | };
13 |
14 | export default Header;
15 |
--------------------------------------------------------------------------------
/examples/vercel-blog-starter/src/app/_components/post-body.tsx:
--------------------------------------------------------------------------------
1 | import markdownStyles from "./markdown-styles.module.css";
2 |
3 | type Props = {
4 | content: string;
5 | };
6 |
7 | export function PostBody({ content }: Props) {
8 | return (
9 |
12 | );
13 | }
14 |
--------------------------------------------------------------------------------
/examples/e2e/app-router/app/methods/get/query/route.ts:
--------------------------------------------------------------------------------
1 | import type { NextRequest } from "next/server";
2 |
3 | export function GET(request: NextRequest) {
4 | const searchParams = request.nextUrl.searchParams;
5 | const query = searchParams.get("query");
6 | if (query === "OpenNext is awesome!") {
7 | return Response.json({ query });
8 | }
9 | return new Response("Internal Server Error", { status: 500 });
10 | }
11 |
--------------------------------------------------------------------------------
/examples/e2e/pages-router/src/pages/api/hello.ts:
--------------------------------------------------------------------------------
1 | // Next.js API route support: https://nextjs.org/docs/pages/building-your-application/routing/api-routes
2 | import type { NextApiRequest, NextApiResponse } from "next";
3 |
4 | type Data = {
5 | hello: string;
6 | };
7 |
8 | export default function handler(req: NextApiRequest, res: NextApiResponse) {
9 | res.status(200).json({ hello: "OpenNext rocks!" });
10 | }
11 |
--------------------------------------------------------------------------------
/examples/overrides/memory-queue/open-next.config.ts:
--------------------------------------------------------------------------------
1 | import { defineCloudflareConfig } from "@opennextjs/cloudflare";
2 | import kvIncrementalCache from "@opennextjs/cloudflare/overrides/incremental-cache/kv-incremental-cache";
3 | import memoryQueue from "@opennextjs/cloudflare/overrides/queue/memory-queue";
4 |
5 | export default defineCloudflareConfig({
6 | incrementalCache: kvIncrementalCache,
7 | queue: memoryQueue,
8 | });
9 |
--------------------------------------------------------------------------------
/examples/playground14/middleware.js:
--------------------------------------------------------------------------------
1 | import { NextResponse } from "next/server";
2 |
3 | export function middleware() {
4 | return NextResponse.json({
5 | "nodejs-instrumentation-setup": globalThis["__NODEJS_INSTRUMENTATION_SETUP"],
6 | "edge-instrumentation-setup": globalThis["__EDGE_INSTRUMENTATION_SETUP"],
7 | });
8 | }
9 |
10 | export const config = {
11 | matcher: ["/middleware-instrumentation"],
12 | };
13 |
--------------------------------------------------------------------------------
/examples/playground15/middleware.js:
--------------------------------------------------------------------------------
1 | import { NextResponse } from "next/server";
2 |
3 | export function middleware() {
4 | return NextResponse.json({
5 | "nodejs-instrumentation-setup": globalThis["__NODEJS_INSTRUMENTATION_SETUP"],
6 | "edge-instrumentation-setup": globalThis["__EDGE_INSTRUMENTATION_SETUP"],
7 | });
8 | }
9 |
10 | export const config = {
11 | matcher: ["/middleware-instrumentation"],
12 | };
13 |
--------------------------------------------------------------------------------
/examples/vercel-blog-starter/src/app/_components/post-title.tsx:
--------------------------------------------------------------------------------
1 | import { ReactNode } from "react";
2 |
3 | type Props = {
4 | children?: ReactNode;
5 | };
6 |
7 | export function PostTitle({ children }: Props) {
8 | return (
9 |
10 | {children}
11 |
12 | );
13 | }
14 |
--------------------------------------------------------------------------------
/examples/e2e/app-pages-router/pages/pages_ssr/index.tsx:
--------------------------------------------------------------------------------
1 | import type { InferGetServerSidePropsType } from "next";
2 |
3 | export async function getServerSideProps() {
4 | return {
5 | props: {
6 | time: new Date().toISOString(),
7 | },
8 | };
9 | }
10 |
11 | export default function Page({ time }: InferGetServerSidePropsType) {
12 | return Time: {time}
;
13 | }
14 |
--------------------------------------------------------------------------------
/examples/next-partial-prerendering/components/product-low-stock-warning.tsx:
--------------------------------------------------------------------------------
1 | export const ProductLowStockWarning = ({ stock }: { stock: number }) => {
2 | if (stock > 3) {
3 | return null;
4 | }
5 |
6 | if (stock === 0) {
7 | return Out of stock
;
8 | }
9 |
10 | return (
11 | Only {stock} left in stock
12 | );
13 | };
14 |
--------------------------------------------------------------------------------
/examples/ssg-app/wrangler.jsonc:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "node_modules/wrangler/config-schema.json",
3 | "main": ".open-next/worker.js",
4 | "name": "ssg-app",
5 | "compatibility_date": "2025-02-04",
6 | "compatibility_flags": ["nodejs_compat", "global_fetch_strictly_public"],
7 | "assets": {
8 | "directory": ".open-next/assets",
9 | "binding": "ASSETS"
10 | },
11 | "vars": {
12 | "APP_VERSION": "1.2.345"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/examples/e2e/app-pages-router/app/rewrite-destination/page.tsx:
--------------------------------------------------------------------------------
1 | export default async function RewriteDestination(props: {
2 | searchParams: Promise<{ a: string; multi?: string[] }>;
3 | }) {
4 | const searchParams = await props.searchParams;
5 | return (
6 |
7 |
Rewritten Destination
8 |
a: {searchParams.a}
9 |
multi: {searchParams.multi?.join(", ")}
10 |
11 | );
12 | }
13 |
--------------------------------------------------------------------------------
/examples/e2e/app-pages-router/pages/pages_isr/index.tsx:
--------------------------------------------------------------------------------
1 | import type { InferGetStaticPropsType } from "next";
2 |
3 | export async function getStaticProps() {
4 | return {
5 | props: {
6 | time: new Date().toISOString(),
7 | },
8 | revalidate: 10,
9 | };
10 | }
11 |
12 | export default function Page({ time }: InferGetStaticPropsType) {
13 | return Time: {time}
;
14 | }
15 |
--------------------------------------------------------------------------------
/examples/e2e/app-router/app/api/after/ssg/route.ts:
--------------------------------------------------------------------------------
1 | import { unstable_cache } from "next/cache";
2 | import { NextResponse } from "next/server";
3 |
4 | export const dynamic = "force-static";
5 |
6 | export async function GET() {
7 | const dateFn = unstable_cache(async () => new Date().toISOString(), ["date"], {
8 | tags: ["date"],
9 | });
10 | const date = await dateFn();
11 | return NextResponse.json({ date });
12 | }
13 |
--------------------------------------------------------------------------------
/examples/e2e/pages-router/e2e/middleware.test.ts:
--------------------------------------------------------------------------------
1 | import { expect, test } from "playwright/test";
2 |
3 | test("should return 500 on middleware error", async ({ request }) => {
4 | const response = await request.get("/", {
5 | headers: {
6 | "x-throw": "true",
7 | },
8 | });
9 | const body = await response.text();
10 | expect(response.status()).toBe(500);
11 | expect(body).toContain("Internal Server Error");
12 | });
13 |
--------------------------------------------------------------------------------
/examples/e2e/pages-router/src/pages/api/revalidate.ts:
--------------------------------------------------------------------------------
1 | import type { NextApiRequest, NextApiResponse } from "next";
2 |
3 | export default async function handler(req: NextApiRequest, res: NextApiResponse) {
4 | try {
5 | await res.revalidate("/ssg/");
6 | return res.json({ hello: "OpenNext rocks!" });
7 | } catch (e) {
8 | console.error(e);
9 | return res.status(500).json({ error: "An error occurred" });
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/examples/middleware/app/layout.tsx:
--------------------------------------------------------------------------------
1 | import type { Metadata } from "next";
2 |
3 | export default function RootLayout({ children }: { children: React.ReactNode }) {
4 | return (
5 |
6 | {children}
7 |
8 | );
9 | }
10 |
11 | export const metadata: Metadata = {
12 | title: "Next.js Middleware example",
13 | description: "Redirect and rewrite pages using Next.js Middleware.",
14 | };
15 |
--------------------------------------------------------------------------------
/examples/overrides/static-assets-incremental-cache/wrangler.jsonc:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "node_modules/wrangler/config-schema.json",
3 | "main": ".open-next/worker.js",
4 | "name": "static-assets-incremental-cache",
5 | "compatibility_date": "2025-02-04",
6 | "compatibility_flags": ["nodejs_compat", "global_fetch_strictly_public"],
7 | "assets": {
8 | "directory": ".open-next/assets",
9 | "binding": "ASSETS"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/examples/prisma/next.config.ts:
--------------------------------------------------------------------------------
1 | import type { NextConfig } from "next";
2 |
3 | const nextConfig: NextConfig = {
4 | /* config options here */
5 | serverExternalPackages: ["@prisma/client", ".prisma/client"],
6 | typescript: {
7 | ignoreBuildErrors: true,
8 | },
9 | };
10 |
11 | import { initOpenNextCloudflareForDev } from "@opennextjs/cloudflare";
12 | initOpenNextCloudflareForDev();
13 |
14 | export default nextConfig;
15 |
--------------------------------------------------------------------------------
/examples/vercel-blog-starter/src/app/_components/avatar.tsx:
--------------------------------------------------------------------------------
1 | type Props = {
2 | name: string;
3 | picture: string;
4 | };
5 |
6 | const Avatar = ({ name, picture }: Props) => {
7 | return (
8 |
9 |

10 |
{name}
11 |
12 | );
13 | };
14 |
15 | export default Avatar;
16 |
--------------------------------------------------------------------------------
/examples/overrides/d1-tag-next/open-next.config.ts:
--------------------------------------------------------------------------------
1 | import { defineCloudflareConfig } from "@opennextjs/cloudflare";
2 | import kvIncrementalCache from "@opennextjs/cloudflare/overrides/incremental-cache/kv-incremental-cache";
3 | import d1NextTagCache from "@opennextjs/cloudflare/overrides/tag-cache/d1-next-tag-cache";
4 |
5 | export default defineCloudflareConfig({
6 | incrementalCache: kvIncrementalCache,
7 | tagCache: d1NextTagCache,
8 | });
9 |
--------------------------------------------------------------------------------
/examples/overrides/kv-tag-next/open-next.config.ts:
--------------------------------------------------------------------------------
1 | import { defineCloudflareConfig } from "@opennextjs/cloudflare";
2 | import kvIncrementalCache from "@opennextjs/cloudflare/overrides/incremental-cache/kv-incremental-cache";
3 | import kvNextTagCache from "@opennextjs/cloudflare/overrides/tag-cache/kv-next-tag-cache";
4 |
5 | export default defineCloudflareConfig({
6 | incrementalCache: kvIncrementalCache,
7 | tagCache: kvNextTagCache,
8 | });
9 |
--------------------------------------------------------------------------------
/.changeset/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://unpkg.com/@changesets/config@3.0.3/schema.json",
3 | "changelog": [
4 | "@changesets/changelog-github",
5 | {
6 | "repo": "opennextjs/opennextjs-cloudflare"
7 | }
8 | ],
9 | "commit": false,
10 | "fixed": [],
11 | "linked": [],
12 | "access": "public",
13 | "baseBranch": "main",
14 | "updateInternalDependencies": "patch",
15 | "ignore": [],
16 | "privatePackages": false
17 | }
18 |
--------------------------------------------------------------------------------
/examples/playground15/app/api/env/route.ts:
--------------------------------------------------------------------------------
1 | // This test relies on using `.dev.vars` to set the environment to `development`
2 | // However `next build` is not passed an environment, so we do not want to cache
3 | // the output.
4 | export const dynamic = "force-dynamic";
5 |
6 | export async function GET() {
7 | return new Response(JSON.stringify(process.env, null, 2), {
8 | headers: { "content-type": "application/json" },
9 | });
10 | }
11 |
--------------------------------------------------------------------------------
/create-cloudflare/next/next.config.ts:
--------------------------------------------------------------------------------
1 | import type { NextConfig } from "next";
2 |
3 | const nextConfig: NextConfig = {
4 | /* config options here */
5 | };
6 |
7 | export default nextConfig;
8 |
9 | // Enable calling `getCloudflareContext()` in `next dev`.
10 | // See https://opennext.js.org/cloudflare/bindings#local-access-to-bindings.
11 | import { initOpenNextCloudflareForDev } from "@opennextjs/cloudflare";
12 | initOpenNextCloudflareForDev();
13 |
--------------------------------------------------------------------------------
/examples/bugs/gh-119/app/globals.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
5 | :root {
6 | --background: #ffffff;
7 | --foreground: #171717;
8 | }
9 |
10 | @media (prefers-color-scheme: dark) {
11 | :root {
12 | --background: #0a0a0a;
13 | --foreground: #ededed;
14 | }
15 | }
16 |
17 | body {
18 | color: var(--foreground);
19 | background: var(--background);
20 | font-family: Arial, Helvetica, sans-serif;
21 | }
22 |
--------------------------------------------------------------------------------
/examples/bugs/gh-119/tailwind.config.ts:
--------------------------------------------------------------------------------
1 | import type { Config } from "tailwindcss";
2 |
3 | export default {
4 | content: [
5 | "./pages/**/*.{js,ts,jsx,tsx,mdx}",
6 | "./components/**/*.{js,ts,jsx,tsx,mdx}",
7 | "./app/**/*.{js,ts,jsx,tsx,mdx}",
8 | ],
9 | theme: {
10 | extend: {
11 | colors: {
12 | background: "var(--background)",
13 | foreground: "var(--foreground)",
14 | },
15 | },
16 | },
17 | plugins: [],
18 | } satisfies Config;
19 |
--------------------------------------------------------------------------------
/examples/bugs/gh-219/src/app/globals.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
5 | :root {
6 | --background: #ffffff;
7 | --foreground: #171717;
8 | }
9 |
10 | @media (prefers-color-scheme: dark) {
11 | :root {
12 | --background: #0a0a0a;
13 | --foreground: #ededed;
14 | }
15 | }
16 |
17 | body {
18 | color: var(--foreground);
19 | background: var(--background);
20 | font-family: Arial, Helvetica, sans-serif;
21 | }
22 |
--------------------------------------------------------------------------------
/examples/e2e/app-pages-router/open-next.config.ts:
--------------------------------------------------------------------------------
1 | import { defineCloudflareConfig } from "@opennextjs/cloudflare";
2 | import r2IncrementalCache from "@opennextjs/cloudflare/overrides/incremental-cache/r2-incremental-cache";
3 | import memoryQueue from "@opennextjs/cloudflare/overrides/queue/memory-queue";
4 |
5 | export default defineCloudflareConfig({
6 | incrementalCache: r2IncrementalCache,
7 | queue: memoryQueue,
8 | enableCacheInterception: true,
9 | });
10 |
--------------------------------------------------------------------------------
/create-cloudflare/next/open-next.config.ts:
--------------------------------------------------------------------------------
1 | import { defineCloudflareConfig } from "@opennextjs/cloudflare";
2 |
3 | export default defineCloudflareConfig({
4 | // Uncomment to enable R2 cache,
5 | // It should be imported as:
6 | // `import r2IncrementalCache from "@opennextjs/cloudflare/overrides/incremental-cache/r2-incremental-cache";`
7 | // See https://opennext.js.org/cloudflare/caching for more details
8 | // incrementalCache: r2IncrementalCache,
9 | });
10 |
--------------------------------------------------------------------------------
/examples/e2e/pages-router/src/middleware.ts:
--------------------------------------------------------------------------------
1 | import type { NextRequest } from "next/server";
2 | import { NextResponse } from "next/server";
3 |
4 | export function middleware(request: NextRequest) {
5 | if (request.headers.get("x-throw")) {
6 | throw new Error("Middleware error");
7 | }
8 | return NextResponse.next({
9 | headers: {
10 | "x-from-middleware": "true",
11 | },
12 | });
13 | }
14 |
15 | export const config = {
16 | matcher: ["/"],
17 | };
18 |
--------------------------------------------------------------------------------
/examples/e2e/experimental/src/app/ppr/page.tsx:
--------------------------------------------------------------------------------
1 | import { DynamicComponent } from "@/components/dynamic";
2 | import { StaticComponent } from "@/components/static";
3 | import { Suspense } from "react";
4 |
5 | export const experimental_ppr = true;
6 |
7 | export default function PPRPage() {
8 | return (
9 |
10 |
11 | Loading...
}>
12 |
13 |
14 |
15 | );
16 | }
17 |
--------------------------------------------------------------------------------
/examples/e2e/pages-router/e2e/404.test.ts:
--------------------------------------------------------------------------------
1 | import { expect, test } from "@playwright/test";
2 |
3 | test("should return 404 on a route not corresponding to any route", async ({ page }) => {
4 | const result = await page.goto("/not-existing/route");
5 | expect(result).toBeDefined();
6 | expect(result?.status()).toBe(404);
7 | const headers = result?.headers();
8 | expect(headers?.["cache-control"]).toBe("private, no-cache, no-store, max-age=0, must-revalidate");
9 | });
10 |
--------------------------------------------------------------------------------
/examples/e2e/shared/components/Album/Album.tsx:
--------------------------------------------------------------------------------
1 | import type { Album } from "../../api/index";
2 | import Song from "./Song";
3 |
4 | type Props = {
5 | album: Album;
6 | };
7 | export default function Album({ album }: Props) {
8 | return (
9 |
10 |
Album: {album.album}
11 |
Artist: {album.artist}
12 | {album.songs.map((song) => (
13 |
14 | ))}
15 |
16 | );
17 | }
18 |
--------------------------------------------------------------------------------
/examples/e2e/shared/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@example/shared",
3 | "version": "0.0.0",
4 | "private": true,
5 | "scripts": {
6 | "clean": "rm -rf .turbo && rm -rf node_modules"
7 | },
8 | "dependencies": {
9 | "react": "catalog:e2e",
10 | "react-dom": "catalog:e2e"
11 | },
12 | "devDependencies": {
13 | "@types/react": "catalog:e2e",
14 | "@types/react-dom": "catalog:e2e"
15 | },
16 | "peerDependencies": {
17 | "next": "catalog:e2e"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/benchmarking/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json.schemastore.org/tsconfig",
3 | "extends": "@tsconfig/strictest/tsconfig.json",
4 | "compilerOptions": {
5 | "target": "ESNext",
6 | "module": "ESNext",
7 | "lib": ["ESNext"],
8 | "types": ["node"],
9 | "moduleResolution": "Bundler",
10 | "forceConsistentCasingInFileNames": true,
11 | "noImplicitReturns": false,
12 | "exactOptionalPropertyTypes": false
13 | },
14 | "include": ["./src/**/*.ts"]
15 | }
16 |
--------------------------------------------------------------------------------
/create-cloudflare/next/eslint.config.mjs:
--------------------------------------------------------------------------------
1 | import { dirname } from "path";
2 | import { fileURLToPath } from "url";
3 | import { FlatCompat } from "@eslint/eslintrc";
4 |
5 | const __filename = fileURLToPath(import.meta.url);
6 | const __dirname = dirname(__filename);
7 |
8 | const compat = new FlatCompat({
9 | baseDirectory: __dirname,
10 | });
11 |
12 | const eslintConfig = [...compat.extends("next/core-web-vitals", "next/typescript")];
13 |
14 | export default eslintConfig;
15 |
--------------------------------------------------------------------------------
/examples/bugs/gh-219/eslint.config.mjs:
--------------------------------------------------------------------------------
1 | import { dirname } from "path";
2 | import { fileURLToPath } from "url";
3 | import { FlatCompat } from "@eslint/eslintrc";
4 |
5 | const __filename = fileURLToPath(import.meta.url);
6 | const __dirname = dirname(__filename);
7 |
8 | const compat = new FlatCompat({
9 | baseDirectory: __dirname,
10 | });
11 |
12 | const eslintConfig = [...compat.extends("next/core-web-vitals", "next/typescript")];
13 |
14 | export default eslintConfig;
15 |
--------------------------------------------------------------------------------
/examples/bugs/gh-219/tailwind.config.ts:
--------------------------------------------------------------------------------
1 | import type { Config } from "tailwindcss";
2 |
3 | export default {
4 | content: [
5 | "./src/pages/**/*.{js,ts,jsx,tsx,mdx}",
6 | "./src/components/**/*.{js,ts,jsx,tsx,mdx}",
7 | "./src/app/**/*.{js,ts,jsx,tsx,mdx}",
8 | ],
9 | theme: {
10 | extend: {
11 | colors: {
12 | background: "var(--background)",
13 | foreground: "var(--foreground)",
14 | },
15 | },
16 | },
17 | plugins: [],
18 | } satisfies Config;
19 |
--------------------------------------------------------------------------------
/examples/middleware/wrangler.jsonc:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "node_modules/wrangler/config-schema.json",
3 | "main": ".open-next/worker.js",
4 | "name": "middleware",
5 | "compatibility_date": "2024-12-30",
6 | "compatibility_flags": ["nodejs_compat", "global_fetch_strictly_public"],
7 | "assets": {
8 | "directory": ".open-next/assets",
9 | "binding": "ASSETS"
10 | },
11 | "vars": {
12 | "MY_VAR": "my-var"
13 | },
14 | "kv_namespaces": [{ "binding": "MY_KV", "id": "" }]
15 | }
16 |
--------------------------------------------------------------------------------
/examples/bugs/gh-223/app/api/image/route.ts:
--------------------------------------------------------------------------------
1 | import { NextRequest, NextResponse } from "next/server";
2 |
3 | import { getImageUrl } from "../../../src/utils/s3Bucket";
4 |
5 | export async function GET(request: NextRequest) {
6 | const searchParams = request.nextUrl.searchParams;
7 | const fileName = searchParams.get("fileName");
8 | return NextResponse.json(
9 | {
10 | image: fileName ? await getImageUrl(fileName) : "",
11 | },
12 | {
13 | status: 200,
14 | }
15 | );
16 | }
17 |
--------------------------------------------------------------------------------
/examples/create-next-app/tailwind.config.ts:
--------------------------------------------------------------------------------
1 | import type { Config } from "tailwindcss";
2 |
3 | const config: Config = {
4 | content: [
5 | "./src/pages/**/*.{js,ts,jsx,tsx,mdx}",
6 | "./src/components/**/*.{js,ts,jsx,tsx,mdx}",
7 | "./src/app/**/*.{js,ts,jsx,tsx,mdx}",
8 | ],
9 | theme: {
10 | extend: {
11 | colors: {
12 | background: "var(--background)",
13 | foreground: "var(--foreground)",
14 | },
15 | },
16 | },
17 | plugins: [],
18 | };
19 | export default config;
20 |
--------------------------------------------------------------------------------
/examples/vercel-blog-starter/public/favicon/site.webmanifest:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Next.js",
3 | "short_name": "Next.js",
4 | "icons": [
5 | {
6 | "src": "/favicons/android-chrome-192x192.png",
7 | "sizes": "192x192",
8 | "type": "image/png"
9 | },
10 | {
11 | "src": "/favicons/android-chrome-512x512.png",
12 | "sizes": "512x512",
13 | "type": "image/png"
14 | }
15 | ],
16 | "theme_color": "#000000",
17 | "background_color": "#000000",
18 | "display": "standalone"
19 | }
20 |
--------------------------------------------------------------------------------
/examples/e2e/pages-router/src/pages/fallback-intercepted/ssg.tsx:
--------------------------------------------------------------------------------
1 | import type { InferGetStaticPropsType } from "next";
2 |
3 | export function getStaticProps() {
4 | return {
5 | props: {
6 | message: "This is a static ssg page.",
7 | },
8 | };
9 | }
10 |
11 | export default function Page({ message }: InferGetStaticPropsType) {
12 | return (
13 |
14 |
Static Fallback Page
15 |
{message}
16 |
17 | );
18 | }
19 |
--------------------------------------------------------------------------------
/examples/next-partial-prerendering/components/ping.tsx:
--------------------------------------------------------------------------------
1 | export function Ping() {
2 | return (
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | );
12 | }
13 |
--------------------------------------------------------------------------------
/examples/prisma/wrangler.jsonc:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "node_modules/wrangler/config-schema.json",
3 | "main": ".open-next/worker.js",
4 | "name": "api",
5 | "compatibility_date": "2024-12-30",
6 | "compatibility_flags": ["nodejs_compat", "global_fetch_strictly_public"],
7 | "assets": {
8 | "directory": ".open-next/assets",
9 | "binding": "ASSETS"
10 | },
11 | "d1_databases": [
12 | {
13 | "binding": "DB",
14 | "database_name": "db",
15 | "database_id": ""
16 | }
17 | ]
18 | }
19 |
--------------------------------------------------------------------------------
/examples/e2e/app-router/e2e/isr.revalidate.test.ts:
--------------------------------------------------------------------------------
1 | import { expect, test } from "@playwright/test";
2 |
3 | test("Test revalidate", async ({ request }) => {
4 | const result = await request.get("/api/isr");
5 |
6 | expect(result.status()).toEqual(200);
7 | const json = await result.json();
8 | const body = json.body;
9 |
10 | expect(json.status).toEqual(200);
11 | expect(body.result).toEqual(true);
12 | expect(body.cacheControl).toEqual("private, no-cache, no-store, max-age=0, must-revalidate");
13 | });
14 |
--------------------------------------------------------------------------------
/examples/e2e/app-router/tailwind.config.ts:
--------------------------------------------------------------------------------
1 | import type { Config } from "tailwindcss";
2 |
3 | const config: Config = {
4 | content: ["./app/**/*.{js,ts,jsx,tsx,mdx}", "../../examples/shared/**/*.{jsx,tsx}"],
5 | theme: {
6 | extend: {
7 | backgroundImage: {
8 | "gradient-radial": "radial-gradient(var(--tw-gradient-stops))",
9 | "gradient-conic": "conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))",
10 | },
11 | },
12 | },
13 | plugins: [],
14 | };
15 | export default config;
16 |
--------------------------------------------------------------------------------
/examples/e2e/experimental/next.config.ts:
--------------------------------------------------------------------------------
1 | import type { NextConfig } from "next";
2 |
3 | const nextConfig: NextConfig = {
4 | /* config options here */
5 | cleanDistDir: true,
6 | output: "standalone",
7 | eslint: {
8 | ignoreDuringBuilds: true,
9 | },
10 | typescript: {
11 | // Ignore type errors during build for now, we'll need to figure this out later
12 | ignoreBuildErrors: true,
13 | },
14 | experimental: {
15 | cacheComponents: true,
16 | },
17 | };
18 |
19 | export default nextConfig;
20 |
--------------------------------------------------------------------------------
/examples/e2e/experimental/src/components/dynamic.tsx:
--------------------------------------------------------------------------------
1 | import { setTimeout } from "node:timers/promises";
2 | import { headers } from "next/headers";
3 |
4 | export async function DynamicComponent() {
5 | const _headers = await headers();
6 | // Simulate a delay to mimic server-side calls
7 | await setTimeout(1000, new Date().toString());
8 | return (
9 |
10 |
Dynamic Component
11 |
This component should be SSR
12 |
{_headers.get("referer")}
13 |
14 | );
15 | }
16 |
--------------------------------------------------------------------------------
/examples/e2e/pages-router/src/pages/ssg/index.tsx:
--------------------------------------------------------------------------------
1 | import type { InferGetStaticPropsType } from "next";
2 |
3 | export async function getStaticProps() {
4 | return {
5 | props: {
6 | time: new Date().toISOString(),
7 | },
8 | };
9 | }
10 |
11 | export default function Page({ time }: InferGetStaticPropsType) {
12 | return (
13 |
14 |
15 | Time: {time}
16 |
17 |
Home
18 |
19 | );
20 | }
21 |
--------------------------------------------------------------------------------
/examples/next-partial-prerendering/lib/delay.ts:
--------------------------------------------------------------------------------
1 | // Times are in milliseconds
2 | export const delayShippingEstimate = 2000;
3 | export const delayRecommendedProducts = 5000;
4 | export const delayReviews = 6000;
5 |
6 | export async function withDelay(
7 | promise: Promise,
8 | delay: number,
9 | ): Promise {
10 | // Ensure we throw if this throws
11 | const ret = await promise;
12 | return new Promise((resolve) => {
13 | setTimeout(() => {
14 | resolve(ret);
15 | }, delay);
16 | });
17 | }
18 |
--------------------------------------------------------------------------------
/examples/e2e/app-pages-router/tailwind.config.ts:
--------------------------------------------------------------------------------
1 | import type { Config } from "tailwindcss";
2 |
3 | const config: Config = {
4 | content: ["./app/**/*.{js,ts,jsx,tsx,mdx}", "../../examples/shared/**/*.{jsx,tsx}"],
5 | theme: {
6 | extend: {
7 | backgroundImage: {
8 | "gradient-radial": "radial-gradient(var(--tw-gradient-stops))",
9 | "gradient-conic": "conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))",
10 | },
11 | },
12 | },
13 | plugins: [],
14 | };
15 | export default config;
16 |
--------------------------------------------------------------------------------
/examples/playground15/e2e/image.test.ts:
--------------------------------------------------------------------------------
1 | import { test, expect } from "@playwright/test";
2 |
3 | test.describe("next/image with trailing slash", () => {
4 | test("next/image with trailing slash", async ({ page }) => {
5 | await page.goto("/image");
6 | await expect(page.getByAltText("Picture of Tomine")).toBeVisible();
7 | // The trailing slash should only be there if trailingSlash is enabled in next.config.ts
8 | expect(await page.getAttribute("img", "src")).toMatch(/^\/_next\/image\//);
9 | });
10 | });
11 |
--------------------------------------------------------------------------------
/examples/e2e/app-router/app/api/after/revalidate/route.ts:
--------------------------------------------------------------------------------
1 | import { revalidateTag } from "next/cache";
2 | import { NextResponse, after } from "next/server";
3 |
4 | export function POST() {
5 | after(
6 | () =>
7 | new Promise((resolve) =>
8 | setTimeout(() => {
9 | revalidateTag("date", {
10 | // We want to expire the "date" tag immediately
11 | expire: 0,
12 | });
13 | resolve();
14 | }, 5000)
15 | )
16 | );
17 |
18 | return NextResponse.json({ success: true });
19 | }
20 |
--------------------------------------------------------------------------------
/examples/e2e/app-router/app/methods/post/formdata/route.ts:
--------------------------------------------------------------------------------
1 | export async function POST(request: Request) {
2 | const formData = await request.formData();
3 | const name = formData.get("name");
4 | const email = formData.get("email");
5 | if (name === "OpenNext [] () %!%$#" && email === "opennext@opennext.com") {
6 | return Response.json(
7 | {
8 | message: "ok",
9 | },
10 | {
11 | status: 202,
12 | }
13 | );
14 | }
15 | return Response.json({ message: "forbidden" }, { status: 403 });
16 | }
17 |
--------------------------------------------------------------------------------
/examples/next-partial-prerendering/components/product-rating.tsx:
--------------------------------------------------------------------------------
1 | import { StarIcon } from '@heroicons/react/24/solid';
2 | import clsx from 'clsx';
3 |
4 | export const ProductRating = ({ rating }: { rating: number }) => {
5 | return (
6 |
7 | {Array.from({ length: 5 }).map((_, i) => {
8 | return (
9 |
13 | );
14 | })}
15 |
16 | );
17 | };
18 |
--------------------------------------------------------------------------------
/examples/middleware/e2e/cloudflare-context.spec.ts:
--------------------------------------------------------------------------------
1 | import { test, expect } from "@playwright/test";
2 |
3 | test.describe("middleware/cloudflare-context", () => {
4 | test("middlewares have access to the cloudflare context", async ({ page }) => {
5 | await page.goto("/middleware");
6 | const cloudflareContextHeaderElement = page.getByTestId("cloudflare-context-header");
7 | expect(await cloudflareContextHeaderElement.textContent()).toContain(
8 | "typeof `cloudflareContext.env` = object"
9 | );
10 | });
11 | });
12 |
--------------------------------------------------------------------------------
/examples/e2e/pages-router/src/pages/fallback-intercepted/[...slugs].tsx:
--------------------------------------------------------------------------------
1 | import type { InferGetServerSidePropsType } from "next";
2 |
3 | export function getServerSideProps() {
4 | return {
5 | props: {
6 | message: "This is a dynamic fallback page.",
7 | },
8 | };
9 | }
10 |
11 | export default function Page({ message }: InferGetServerSidePropsType) {
12 | return (
13 |
14 |
Dynamic Fallback Page
15 |
{message}
16 |
17 | );
18 | }
19 |
--------------------------------------------------------------------------------
/examples/e2e/pages-router/src/pages/isr/index.tsx:
--------------------------------------------------------------------------------
1 | import type { InferGetStaticPropsType } from "next";
2 | import Link from "next/link";
3 |
4 | export async function getStaticProps() {
5 | return {
6 | props: {
7 | time: new Date().toISOString(),
8 | },
9 | revalidate: 10,
10 | };
11 | }
12 |
13 | export default function Page({ time }: InferGetStaticPropsType) {
14 | return (
15 |
16 |
Time: {time}
17 |
Home
18 |
19 | );
20 | }
21 |
--------------------------------------------------------------------------------
/examples/ssg-app/app/page.tsx:
--------------------------------------------------------------------------------
1 | import styles from "./page.module.css";
2 | import { getCloudflareContext } from "@opennextjs/cloudflare";
3 |
4 | export default async function Home() {
5 | const cloudflareContext = await getCloudflareContext({
6 | async: true,
7 | });
8 |
9 | return (
10 |
11 |
12 | Hello from a Statically generated page
13 | {cloudflareContext.env.MY_SECRET}
14 |
15 |
16 | );
17 | }
18 |
--------------------------------------------------------------------------------
/packages/cloudflare/src/cli/build/utils/version.ts:
--------------------------------------------------------------------------------
1 | import { createRequire } from "node:module";
2 | import { join } from "node:path";
3 | import { fileURLToPath, URL } from "node:url";
4 |
5 | export function getVersion() {
6 | const require = createRequire(import.meta.url);
7 | const __dirname = fileURLToPath(new URL(".", import.meta.url));
8 | const pkgJson = require(join(__dirname, "../../../../package.json"));
9 | return {
10 | cloudflare: pkgJson.version,
11 | aws: pkgJson.dependencies["@opennextjs/aws"],
12 | };
13 | }
14 |
--------------------------------------------------------------------------------
/.changeset/README.md:
--------------------------------------------------------------------------------
1 | # Changesets
2 |
3 | Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works
4 | with multi-package repos, or single-package repos to help you version and publish your code. You can
5 | find the full documentation for it [in our repository](https://github.com/changesets/changesets)
6 |
7 | We have a quick list of common questions to get you started engaging with this project in
8 | [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)
9 |
--------------------------------------------------------------------------------
/examples/e2e/app-router/app/revalidate-tag/layout.tsx:
--------------------------------------------------------------------------------
1 | import { unstable_cache } from "next/cache";
2 | import type { ReactNode } from "react";
3 |
4 | export default async function Layout({ children }: { children: ReactNode }) {
5 | const fakeFetch = unstable_cache(async () => new Date().getTime(), ["fakeFetch"], {
6 | tags: ["revalidate"],
7 | });
8 | const fetchedDate = await fakeFetch();
9 | return (
10 |
11 |
Fetched time: {new Date(fetchedDate).toISOString()}
12 | {children}
13 |
14 | );
15 | }
16 |
--------------------------------------------------------------------------------
/examples/playground15/e2e/cloudflare.spec.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Cloudflare specific tests.
3 | *
4 | * The tests in this file do not run on Node (`next dev`).
5 | */
6 |
7 | import { test, expect } from "@playwright/test";
8 |
9 | test.describe("playground/cloudflare", () => {
10 | test("NextConfig", async ({ page }) => {
11 | const res = await page.request.get("/api/buildid");
12 | expect(res.status()).toEqual(200);
13 | const { nextConfig } = await res.json();
14 | expect(nextConfig.output).toEqual("standalone");
15 | });
16 | });
17 |
--------------------------------------------------------------------------------
/examples/overrides/memory-queue/app/page.tsx:
--------------------------------------------------------------------------------
1 | import styles from "./page.module.css";
2 |
3 | export const revalidate = 5;
4 |
5 | export default async function Home() {
6 | // We purposefully wait for 2 seconds to allow deduplication to occur
7 | await new Promise((resolve) => setTimeout(resolve, 2000));
8 | return (
9 |
10 |
11 | Hello from a Statically generated page
12 | {Date.now()}
13 |
14 |
15 | );
16 | }
17 |
--------------------------------------------------------------------------------
/examples/create-next-app/src/app/globals.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
5 | :root {
6 | --background: #ffffff;
7 | --foreground: #171717;
8 | }
9 |
10 | @media (prefers-color-scheme: dark) {
11 | :root {
12 | --background: #0a0a0a;
13 | --foreground: #ededed;
14 | }
15 | }
16 |
17 | body {
18 | color: var(--foreground);
19 | background: var(--background);
20 | font-family: Arial, Helvetica, sans-serif;
21 | }
22 |
23 | @layer utilities {
24 | .text-balance {
25 | text-wrap: balance;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/examples/overrides/r2-incremental-cache/app/page.tsx:
--------------------------------------------------------------------------------
1 | import styles from "./page.module.css";
2 |
3 | export const revalidate = 5;
4 |
5 | export default async function Home() {
6 | // We purposefully wait for 2 seconds to allow deduplication to occur
7 | await new Promise((resolve) => setTimeout(resolve, 2000));
8 | return (
9 |
10 |
11 | Hello from a Statically generated page
12 | {Date.now()}
13 |
14 |
15 | );
16 | }
17 |
--------------------------------------------------------------------------------
/examples/playground14/pages/head.tsx:
--------------------------------------------------------------------------------
1 | import Head from "next/head";
2 |
3 | export function getServerSideProps() {
4 | return {
5 | props: {
6 | time: new Date().toISOString(),
7 | },
8 | };
9 | }
10 | export default function Page({ time }) {
11 | return (
12 |
13 |
14 |
SSR Head
15 |
16 |
17 |
18 |
19 | Time: {time}
20 |
21 |
22 | );
23 | }
24 |
--------------------------------------------------------------------------------
/examples/playground15/pages/head.tsx:
--------------------------------------------------------------------------------
1 | import Head from "next/head";
2 |
3 | export function getServerSideProps() {
4 | return {
5 | props: {
6 | time: new Date().toISOString(),
7 | },
8 | };
9 | }
10 | export default function Page({ time }) {
11 | return (
12 |
13 |
14 |
SSR Head
15 |
16 |
17 |
18 |
19 | Time: {time}
20 |
21 |
22 | );
23 | }
24 |
--------------------------------------------------------------------------------
/examples/e2e/app-router/app/layout.tsx:
--------------------------------------------------------------------------------
1 | import "./globals.css";
2 |
3 | import type { Metadata } from "next";
4 | import { Inter } from "next/font/google";
5 |
6 | const inter = Inter({ subsets: ["latin"] });
7 |
8 | export const metadata: Metadata = {
9 | title: "Nextjs App Router",
10 | description: "Generated by create next app",
11 | };
12 |
13 | export default function RootLayout({ children }: { children: React.ReactNode }) {
14 | return (
15 |
16 | {children}
17 |
18 | );
19 | }
20 |
--------------------------------------------------------------------------------
/examples/e2e/pages-router/src/pages/ssr/index.tsx:
--------------------------------------------------------------------------------
1 | import type { InferGetServerSidePropsType } from "next";
2 |
3 | export async function getServerSideProps() {
4 | return {
5 | props: {
6 | time: new Date().toISOString(),
7 | envVar: process.env.SOME_PROD_VAR,
8 | },
9 | };
10 | }
11 |
12 | export default function Page({ time, envVar }: InferGetServerSidePropsType) {
13 | return (
14 | <>
15 | SSR
16 | Time: {time}
17 | Env: {envVar}
18 | >
19 | );
20 | }
21 |
--------------------------------------------------------------------------------
/examples/e2e/app-router/e2e/dynamic.catch-all.hypen.test.ts:
--------------------------------------------------------------------------------
1 | import { expect, test } from "@playwright/test";
2 |
3 | // https://github.com/opennextjs/opennextjs-cloudflare/issues/942
4 | test("Dynamic catch-all API route with hyphen param", async ({ request }) => {
5 | const res = await request.get("/api/auth/opennext/is/really/cool");
6 | expect(res.status()).toBe(200);
7 | expect(res.headers()["content-type"]).toBe("application/json");
8 | const json = await res.json();
9 | expect(json).toStrictEqual({ slugs: ["opennext", "is", "really", "cool"] });
10 | });
11 |
--------------------------------------------------------------------------------
/packages/cloudflare/src/cli/utils/ask-confirmation.ts:
--------------------------------------------------------------------------------
1 | import { randomUUID } from "node:crypto";
2 |
3 | import Enquirer from "enquirer";
4 |
5 | export async function askConfirmation(message: string): Promise {
6 | const questionName = randomUUID();
7 |
8 | const enquirerAnswersObject = await Enquirer.prompt>({
9 | name: questionName,
10 | message,
11 | type: "confirm",
12 | initial: "y",
13 | });
14 |
15 | console.log("");
16 |
17 | const answer = !!enquirerAnswersObject[questionName];
18 | return answer;
19 | }
20 |
--------------------------------------------------------------------------------
/examples/e2e/app-pages-router/e2e/headers.test.ts:
--------------------------------------------------------------------------------
1 | import { expect, test } from "@playwright/test";
2 |
3 | test("does not set x-opennext-requestid header on cache interceptor response", async ({ page }) => {
4 | const result = await page.goto("/ssg");
5 | expect(result).toBeDefined();
6 | expect(result?.status()).toBe(200);
7 | const headers = result?.headers();
8 |
9 | // This header should not be defined even when its a cached response from the cache interception in the external middleware
10 | expect(headers?.["x-opennext-requestid"]).toBeUndefined();
11 | });
12 |
--------------------------------------------------------------------------------
/examples/next-partial-prerendering/components/product-currency-symbol.tsx:
--------------------------------------------------------------------------------
1 | import { toFormat, type Dinero } from 'dinero.js';
2 |
3 | export const ProductCurrencySymbol = ({
4 | dinero,
5 | }: {
6 | dinero: Dinero;
7 | }) => {
8 | let symbol = '';
9 | switch (toFormat(dinero, ({ currency }) => currency.code)) {
10 | case 'GBP': {
11 | symbol = '£';
12 | break;
13 | }
14 |
15 | case 'EUR': {
16 | symbol = '€';
17 | break;
18 | }
19 |
20 | default: {
21 | symbol = '$';
22 | break;
23 | }
24 | }
25 |
26 | return <>{symbol}>;
27 | };
28 |
--------------------------------------------------------------------------------
/packages/cloudflare/src/utils/get-package-templates-dir-path.ts:
--------------------------------------------------------------------------------
1 | import path from "node:path";
2 | import url from "node:url";
3 |
4 | const __filename = url.fileURLToPath(import.meta.url);
5 | const __dirname = path.dirname(__filename);
6 | const templatesDirPath = path.join(__dirname, "/../../templates");
7 |
8 | /**
9 | * Utility for getting the resolved path to the package's templates directory
10 | *
11 | * @returns the resolved path of the templates directory
12 | */
13 | export function getPackageTemplatesDirPath(): string {
14 | return templatesDirPath;
15 | }
16 |
--------------------------------------------------------------------------------
/examples/bugs/gh-223/app/layout.tsx:
--------------------------------------------------------------------------------
1 | import type { Metadata } from "next";
2 | import { Inter } from "next/font/google";
3 | import "./globals.css";
4 |
5 | const inter = Inter({ subsets: ["latin"] });
6 |
7 | export const metadata: Metadata = {
8 | title: "Create Next App",
9 | description: "Generated by create next app",
10 | };
11 |
12 | export default function RootLayout({
13 | children,
14 | }: Readonly<{
15 | children: React.ReactNode;
16 | }>) {
17 | return (
18 |
19 | {children}
20 |
21 | );
22 | }
23 |
--------------------------------------------------------------------------------
/examples/bugs/gh-223/tailwind.config.ts:
--------------------------------------------------------------------------------
1 | import type { Config } from "tailwindcss";
2 |
3 | const config: Config = {
4 | content: [
5 | "./src/pages/**/*.{js,ts,jsx,tsx,mdx}",
6 | "./src/components/**/*.{js,ts,jsx,tsx,mdx}",
7 | "./src/app/**/*.{js,ts,jsx,tsx,mdx}",
8 | ],
9 | theme: {
10 | extend: {
11 | backgroundImage: {
12 | "gradient-radial": "radial-gradient(var(--tw-gradient-stops))",
13 | "gradient-conic": "conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))",
14 | },
15 | },
16 | },
17 | plugins: [],
18 | };
19 | export default config;
20 |
--------------------------------------------------------------------------------
/examples/e2e/experimental/src/app/use-cache/isr/page.tsx:
--------------------------------------------------------------------------------
1 | import { FullyCachedComponent, ISRComponent } from "@/components/cached";
2 | import { Suspense } from "react";
3 |
4 | export default async function Page() {
5 | // Not working for now, need a patch in next to disable full revalidation during ISR revalidation
6 | return (
7 |
8 |
Cache
9 | Loading...}>
10 |
11 |
12 | Loading...}>
13 |
14 |
15 |
16 | );
17 | }
18 |
--------------------------------------------------------------------------------
/examples/middleware/app/page.tsx:
--------------------------------------------------------------------------------
1 | import Link from "next/link";
2 |
3 | export default function Home() {
4 | return (
5 |
6 |
Index
7 |
8 | Go to about page (will redirect)
9 |
10 |
11 | Go to another page (will rewrite)
12 |
13 |
14 | Go to about 2 page (no redirect or rewrite)
15 |
16 |
17 | Go to middleware page (using NextResponse.next())
18 |
19 |
20 | );
21 | }
22 |
--------------------------------------------------------------------------------
/examples/e2e/app-pages-router/app/ssr/page.tsx:
--------------------------------------------------------------------------------
1 | import { headers } from "next/headers";
2 |
3 | async function getTime() {
4 | const res = await new Promise((resolve) => {
5 | setTimeout(() => {
6 | resolve(new Date().toISOString());
7 | }, 1500);
8 | });
9 | return res;
10 | }
11 |
12 | export default async function SSR() {
13 | const time = await getTime();
14 | const headerList = await headers();
15 | return (
16 |
17 |
Time: {time}
18 |
{headerList.get("host")}
19 |
Env: {process.env.SOME_ENV_VAR}
20 |
21 | );
22 | }
23 |
--------------------------------------------------------------------------------
/examples/playground14/e2e/head.spec.ts:
--------------------------------------------------------------------------------
1 | import { test, expect } from "@playwright/test";
2 |
3 | test.describe("head properly populated", () => {
4 | test("should properly populate the ", async ({ page }) => {
5 | await page.goto("/head");
6 | const title = await page.title();
7 | const description = await page.locator('meta[name="description"]').getAttribute("content");
8 | const favicon = await page.locator('link[rel="icon"]').getAttribute("href");
9 | expect(title).toBe("SSR Head");
10 | expect(description).toBe("SSR");
11 | expect(favicon).toBe("/favicon.ico");
12 | });
13 | });
14 |
--------------------------------------------------------------------------------
/examples/playground15/app/other-app/page.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 | import testImage from "../../public/test.jpg";
3 | import Image from "next/image";
4 |
5 | export default function Page() {
6 | return (
7 | <>
8 | other app
9 |
10 | {process.env.NEXT_DEPLOYMENT_ID}
11 |
12 |
22 | >
23 | );
24 | }
25 |
--------------------------------------------------------------------------------
/examples/playground15/e2e/head.spec.ts:
--------------------------------------------------------------------------------
1 | import { test, expect } from "@playwright/test";
2 |
3 | test.describe("head properly populated", () => {
4 | test("should properly populate the ", async ({ page }) => {
5 | await page.goto("/head");
6 | const title = await page.title();
7 | const description = await page.locator('meta[name="description"]').getAttribute("content");
8 | const favicon = await page.locator('link[rel="icon"]').getAttribute("href");
9 | expect(title).toBe("SSR Head");
10 | expect(description).toBe("SSR");
11 | expect(favicon).toBe("/favicon.ico");
12 | });
13 | });
14 |
--------------------------------------------------------------------------------
/examples/e2e/shared/components/Album/index.tsx:
--------------------------------------------------------------------------------
1 | import Link from "next/link";
2 |
3 | import type { Album } from "../../api/index";
4 | import Song from "./Song";
5 |
6 | type Props = {
7 | album: Album;
8 | };
9 | export default function Album({ album }: Props) {
10 | return (
11 |
12 |
Album: {album.album}
13 |
Artist: {album.artist}
14 | {album.songs.map((song) => (
15 |
16 |
17 |
18 | ))}
19 |
20 | );
21 | }
22 |
--------------------------------------------------------------------------------
/examples/e2e/app-pages-router/app/layout.tsx:
--------------------------------------------------------------------------------
1 | import "./globals.css";
2 |
3 | import type { Metadata } from "next";
4 | import { Inter } from "next/font/google";
5 |
6 | const inter = Inter({ subsets: ["latin"] });
7 |
8 | export const metadata: Metadata = {
9 | title: "Nextjs App Router",
10 | description: "Generated by create next app",
11 | };
12 |
13 | export default function RootLayout({ children }: { children: React.ReactNode }) {
14 | return (
15 |
16 |
17 |
18 | {children}
19 |
20 |
21 | );
22 | }
23 |
--------------------------------------------------------------------------------
/examples/e2e/shared/components/Album/Song.tsx:
--------------------------------------------------------------------------------
1 | import type { Song } from "../../api/index";
2 |
3 | type Props = {
4 | song: Song;
5 | play?: boolean;
6 | };
7 | export default function Song({ song, play }: Props) {
8 | return (
9 |
10 |
Song: {song.title}
11 |
Year: {song.year}
12 | {play && (
13 |
20 | )}
21 |
22 | );
23 | }
24 |
--------------------------------------------------------------------------------
/packages/cloudflare/src/cli/build/utils/test-patch.ts:
--------------------------------------------------------------------------------
1 | import { patchCode } from "@opennextjs/aws/build/patch/astCodePatcher.js";
2 | import { createPatch } from "diff";
3 |
4 | /**
5 | * Compute the diff resulting of applying the `rule` to `src`.
6 | *
7 | * @param filename Filename used in the patch output
8 | * @param src Content of the source code
9 | * @param rule ASTgrep rule
10 | * @returns diff in unified diff format
11 | */
12 | export function computePatchDiff(filename: string, src: string, rule: string): string {
13 | const dst = patchCode(src, rule);
14 | return createPatch(filename, src, dst);
15 | }
16 |
--------------------------------------------------------------------------------
/packages/cloudflare/src/cli/project-options.ts:
--------------------------------------------------------------------------------
1 | import type { WranglerTarget } from "./utils/run-wrangler.js";
2 |
3 | export type ProjectOptions = {
4 | // Next app root folder
5 | sourceDir: string;
6 | // Whether the Next.js build should be skipped (i.e. if the `.next` dir is already built)
7 | skipNextBuild: boolean;
8 | // Whether the check to see if a wrangler config file exists should be skipped
9 | skipWranglerConfigCheck: boolean;
10 | // Whether minification of the worker should be enabled
11 | minify: boolean;
12 | populateCache?: { mode: WranglerTarget; onlyPopulateWithoutBuilding: boolean };
13 | };
14 |
--------------------------------------------------------------------------------
/create-cloudflare/next/src/app/globals.css:
--------------------------------------------------------------------------------
1 | @import "tailwindcss";
2 |
3 | :root {
4 | --background: #ffffff;
5 | --foreground: #171717;
6 | }
7 |
8 | @theme inline {
9 | --color-background: var(--background);
10 | --color-foreground: var(--foreground);
11 | --font-sans: var(--font-geist-sans);
12 | --font-mono: var(--font-geist-mono);
13 | }
14 |
15 | @media (prefers-color-scheme: dark) {
16 | :root {
17 | --background: #0a0a0a;
18 | --foreground: #ededed;
19 | }
20 | }
21 |
22 | body {
23 | background: var(--background);
24 | color: var(--foreground);
25 | font-family: Arial, Helvetica, sans-serif;
26 | }
27 |
--------------------------------------------------------------------------------
/examples/overrides/memory-queue/wrangler.jsonc:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "node_modules/wrangler/config-schema.json",
3 | "main": ".open-next/worker.js",
4 | "name": "memory-queue",
5 | "compatibility_date": "2025-02-04",
6 | "compatibility_flags": ["nodejs_compat", "global_fetch_strictly_public"],
7 | "assets": {
8 | "directory": ".open-next/assets",
9 | "binding": "ASSETS"
10 | },
11 | "kv_namespaces": [
12 | {
13 | "binding": "NEXT_INC_CACHE_KV",
14 | "id": ""
15 | }
16 | ],
17 | "services": [
18 | {
19 | "binding": "WORKER_SELF_REFERENCE",
20 | "service": "memory-queue"
21 | }
22 | ]
23 | }
24 |
--------------------------------------------------------------------------------
/examples/e2e/app-router/app/config-redirect/page.tsx:
--------------------------------------------------------------------------------
1 | export default function RedirectDestination() {
2 | return (
3 |
16 | );
17 | }
18 |
--------------------------------------------------------------------------------
/examples/e2e/app-router/app/globals.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
5 | :root {
6 | --foreground-rgb: 0, 0, 0;
7 | --background-start-rgb: 214, 219, 220;
8 | --background-end-rgb: 255, 255, 255;
9 | }
10 |
11 | @media (prefers-color-scheme: dark) {
12 | :root {
13 | --foreground-rgb: 255, 255, 255;
14 | --background-start-rgb: 0, 0, 0;
15 | --background-end-rgb: 0, 0, 0;
16 | }
17 | }
18 |
19 | body {
20 | color: rgb(var(--foreground-rgb));
21 | background: linear-gradient(to bottom, transparent, rgb(var(--background-end-rgb)))
22 | rgb(var(--background-start-rgb));
23 | }
24 |
--------------------------------------------------------------------------------
/examples/prisma/src/app/page.tsx:
--------------------------------------------------------------------------------
1 | import styles from "./page.module.css";
2 | import { getDb } from "@/lib/db";
3 |
4 | export const dynamic = "force-dynamic";
5 |
6 | export default async function Home() {
7 | const db = getDb();
8 | const allUsers = await db.users.findMany();
9 | return (
10 |
11 |
12 | {allUsers.map((user) => (
13 | -
14 | {user.name}
15 |
16 | {user.email}
17 |
18 | ))}
19 |
20 |
21 | );
22 | }
23 |
--------------------------------------------------------------------------------
/examples/e2e/app-pages-router/app/globals.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
5 | :root {
6 | --foreground-rgb: 0, 0, 0;
7 | --background-start-rgb: 214, 219, 220;
8 | --background-end-rgb: 255, 255, 255;
9 | }
10 |
11 | @media (prefers-color-scheme: dark) {
12 | :root {
13 | --foreground-rgb: 255, 255, 255;
14 | --background-start-rgb: 0, 0, 0;
15 | --background-end-rgb: 0, 0, 0;
16 | }
17 | }
18 |
19 | body {
20 | color: rgb(var(--foreground-rgb));
21 | background: linear-gradient(to bottom, transparent, rgb(var(--background-end-rgb)))
22 | rgb(var(--background-start-rgb));
23 | }
24 |
--------------------------------------------------------------------------------
/examples/e2e/app-router/app/methods/post/cookies/route.ts:
--------------------------------------------------------------------------------
1 | import { cookies } from "next/headers";
2 |
3 | export async function POST(request: Request) {
4 | const formData = await request.formData();
5 | const username = formData.get("username");
6 | const password = formData.get("password");
7 | if (username === "hakuna" && password === "matata") {
8 | (await cookies()).set("auth_session", "SUPER_SECRET_SESSION_ID_1234");
9 | return Response.json(
10 | {
11 | message: "ok",
12 | },
13 | {
14 | status: 202,
15 | }
16 | );
17 | }
18 | return Response.json({ message: "you must login" }, { status: 401 });
19 | }
20 |
--------------------------------------------------------------------------------
/examples/vercel-blog-starter/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 | .yarn/install-state.gz
8 |
9 | # testing
10 | /coverage
11 |
12 | # next.js
13 | /.next/
14 | /out/
15 |
16 | # production
17 | /build
18 |
19 | # misc
20 | .DS_Store
21 | *.pem
22 |
23 | # debug
24 | npm-debug.log*
25 | yarn-debug.log*
26 | yarn-error.log*
27 |
28 | # local env files
29 | .env*.local
30 |
31 | # vercel
32 | .vercel
33 |
34 | # typescript
35 | *.tsbuildinfo
36 | next-env.d.ts
37 |
38 | #cf workers
39 | .wrangler
40 | .worker-next
--------------------------------------------------------------------------------
/.github/workflows/checks.yml:
--------------------------------------------------------------------------------
1 | name: Code checks
2 |
3 | on:
4 | push:
5 | branches: [main, experimental]
6 | pull_request:
7 |
8 | jobs:
9 | checks:
10 | name: ${{ matrix.script }}
11 | runs-on: ubuntu-latest
12 | strategy:
13 | fail-fast: false
14 | matrix:
15 | script: ["prettier:check", "lint:check", "ts:check", "test"]
16 | steps:
17 | - name: Check out code
18 | uses: actions/checkout@v4
19 |
20 | - name: Install Dependencies
21 | uses: ./.github/actions/install-dependencies
22 |
23 | - name: ${{ matrix.script }}
24 | run: pnpm run ${{ matrix.script }}
25 |
--------------------------------------------------------------------------------
/examples/bugs/gh-223/public/vercel.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/e2e/app-router/app/revalidate-path/page.tsx:
--------------------------------------------------------------------------------
1 | export default async function Page() {
2 | const responseSST = await fetch("https://sst.dev", {
3 | next: {
4 | tags: ["path"],
5 | },
6 | });
7 | // This one doesn't have a tag
8 | const responseOpenNext = await fetch("https://opennext.js.org");
9 | const reqIdSst = responseSST.headers.get("x-amz-cf-id");
10 | const dateInOpenNext = responseOpenNext.headers.get("date");
11 | return (
12 |
13 |
Request id from SST
14 |
RequestID: {reqIdSst}
15 |
Date from from OpenNext
16 |
Date: {dateInOpenNext}
17 |
18 | );
19 | }
20 |
--------------------------------------------------------------------------------
/examples/overrides/memory-queue/app/layout.tsx:
--------------------------------------------------------------------------------
1 | import type { Metadata } from "next";
2 | import "./globals.css";
3 |
4 | import { getCloudflareContext } from "@opennextjs/cloudflare";
5 |
6 | export const metadata: Metadata = {
7 | title: "SSG App",
8 | description: "An app in which all the routes are SSG'd",
9 | };
10 |
11 | export default async function RootLayout({
12 | children,
13 | }: Readonly<{
14 | children: React.ReactNode;
15 | }>) {
16 | const cloudflareContext = await getCloudflareContext({
17 | async: true,
18 | });
19 |
20 | return (
21 |
22 | {children}
23 |
24 | );
25 | }
26 |
--------------------------------------------------------------------------------
/examples/create-next-app/public/vercel.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/next-partial-prerendering/components/product-used-price.tsx:
--------------------------------------------------------------------------------
1 | import { Product } from '#/types/product';
2 | import { dinero, toUnit, up, type DineroSnapshot } from 'dinero.js';
3 |
4 | export const ProductUsedPrice = ({
5 | usedPrice: usedPriceRaw,
6 | }: {
7 | usedPrice: Product['usedPrice'];
8 | }) => {
9 | const usedPrice = dinero(usedPriceRaw as DineroSnapshot);
10 |
11 | return (
12 |
13 |
More buying choices
14 |
15 | ${toUnit(usedPrice, { digits: 0, round: up })} (used)
16 |
17 |
18 | );
19 | };
20 |
--------------------------------------------------------------------------------
/examples/next-partial-prerendering/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 | /.yarn
8 |
9 | # testing
10 | /coverage
11 | playwright-report
12 | test-results
13 |
14 | # next.js
15 | /.next/
16 | /out/
17 |
18 | # production
19 | /build
20 |
21 | # misc
22 | .DS_Store
23 | *.pem
24 |
25 | # debug
26 | npm-debug.log*
27 | yarn-debug.log*
28 | yarn-error.log*
29 | .pnpm-debug.log*
30 |
31 | # local env files
32 | .env*
33 | !.env*.example
34 |
35 | # vercel
36 | .vercel
37 |
38 | # typescript
39 | *.tsbuildinfo
40 | next-env.d.ts
41 |
--------------------------------------------------------------------------------
/examples/overrides/d1-tag-next/app/components/revalidationButtons.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { revalidateTagAction, revalidatePathAction } from "../action";
4 |
5 | export default function RevalidationButtons() {
6 | return (
7 |
8 |
16 |
17 |
25 |
26 | );
27 | }
28 |
--------------------------------------------------------------------------------
/examples/overrides/kv-tag-next/app/components/revalidationButtons.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { revalidateTagAction, revalidatePathAction } from "../action";
4 |
5 | export default function RevalidationButtons() {
6 | return (
7 |
8 |
16 |
17 |
25 |
26 | );
27 | }
28 |
--------------------------------------------------------------------------------
/examples/overrides/r2-incremental-cache/app/layout.tsx:
--------------------------------------------------------------------------------
1 | import type { Metadata } from "next";
2 | import "./globals.css";
3 |
4 | import { getCloudflareContext } from "@opennextjs/cloudflare";
5 |
6 | export const metadata: Metadata = {
7 | title: "SSG App",
8 | description: "An app in which all the routes are SSG'd",
9 | };
10 |
11 | export default async function RootLayout({
12 | children,
13 | }: Readonly<{
14 | children: React.ReactNode;
15 | }>) {
16 | const cloudflareContext = await getCloudflareContext({
17 | async: true,
18 | });
19 |
20 | return (
21 |
22 | {children}
23 |
24 | );
25 | }
26 |
--------------------------------------------------------------------------------
/examples/e2e/app-router/app/albums/[album]/[song]/page.tsx:
--------------------------------------------------------------------------------
1 | import { getSong } from "@example/shared/api";
2 |
3 | type Props = {
4 | params: Promise<{
5 | album: string;
6 | song: string;
7 | }>;
8 | };
9 | export default async function Song(props: Props) {
10 | const params = await props.params;
11 | const song = await getSong(params.album, params.song);
12 |
13 | return (
14 |
15 |
Not Modal
16 | {decodeURIComponent(params.album)}
17 |
23 |
24 | );
25 | }
26 |
--------------------------------------------------------------------------------
/examples/e2e/shared/components/Filler/index.tsx:
--------------------------------------------------------------------------------
1 | interface FillerProps {
2 | // Size in kb of the filler
3 | size: number;
4 | }
5 |
6 | //This component is there to demonstrate how you could bypass streaming buffering in aws lambda.
7 | //Hopefully, this will be fixed in the future and this component will be removed.
8 | // https://github.com/aws/aws-lambda-nodejs-runtime-interface-client/issues/94
9 | export default function Filler({ size }: FillerProps) {
10 | const str = "a".repeat(size * 1024);
11 | const byteSize = new TextEncoder().encode(str).length;
12 | return ;
13 | }
14 |
--------------------------------------------------------------------------------
/examples/playground15/next.config.ts:
--------------------------------------------------------------------------------
1 | import { initOpenNextCloudflareForDev, getDeploymentId } from "@opennextjs/cloudflare";
2 | import { NextConfig } from "next";
3 |
4 | initOpenNextCloudflareForDev();
5 |
6 | const nextConfig: NextConfig = {
7 | typescript: { ignoreBuildErrors: true },
8 | eslint: { ignoreDuringBuilds: true },
9 | experimental: {
10 | // Generate source map to validate the fix for opennextjs/opennextjs-cloudflare#341
11 | serverSourceMaps: true,
12 | },
13 | deploymentId: getDeploymentId(),
14 | trailingSlash: true,
15 | images: {
16 | formats: ["image/avif", "image/webp"],
17 | },
18 | };
19 |
20 | export default nextConfig;
21 |
--------------------------------------------------------------------------------
/examples/e2e/pages-router/e2e/trailing.test.ts:
--------------------------------------------------------------------------------
1 | import { expect, test } from "@playwright/test";
2 |
3 | test("trailingSlash redirect", async ({ page }) => {
4 | const response = await page.goto("/ssr");
5 |
6 | expect(response?.request().redirectedFrom()?.url()).toMatch(/\/ssr$/);
7 | expect(response?.request().url()).toMatch(/\/ssr\/$/);
8 | });
9 |
10 | test("trailingSlash redirect with search parameters", async ({ page }) => {
11 | const response = await page.goto("/ssr?happy=true");
12 |
13 | expect(response?.request().redirectedFrom()?.url()).toMatch(/\/ssr\?happy=true$/);
14 | expect(response?.request().url()).toMatch(/\/ssr\/\?happy=true$/);
15 | });
16 |
--------------------------------------------------------------------------------
/examples/e2e/app-pages-router/app/albums/[album]/[song]/page.tsx:
--------------------------------------------------------------------------------
1 | import { getSong } from "@example/shared/api";
2 |
3 | type Props = {
4 | params: Promise<{
5 | album: string;
6 | song: string;
7 | }>;
8 | };
9 | export default async function Song(props: Props) {
10 | const params = await props.params;
11 | const song = await getSong(params.album, params.song);
12 |
13 | return (
14 |
15 |
Not Modal
16 | {decodeURIComponent(params.album)}
17 |
23 |
24 | );
25 | }
26 |
--------------------------------------------------------------------------------
/examples/e2e/pages-router/e2e/i18n.test.ts:
--------------------------------------------------------------------------------
1 | import { expect, test } from "@playwright/test";
2 |
3 | test("Next config headers with i18n", async ({ page }) => {
4 | const responsePromise = page.waitForResponse((response) => {
5 | return response.status() === 200;
6 | });
7 | await page.goto("/");
8 |
9 | const response = await responsePromise;
10 | // Response header should be set
11 | const headers = response.headers();
12 | // Headers from next.config.js should be set
13 | expect(headers["x-custom-header"]).toEqual("my custom header value");
14 |
15 | // Headers from middleware should be set
16 | expect(headers["x-from-middleware"]).toEqual("true");
17 | });
18 |
--------------------------------------------------------------------------------
/examples/overrides/static-assets-incremental-cache/app/components/revalidationButtons.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { revalidateTagAction, revalidatePathAction } from "../action";
4 |
5 | export default function RevalidationButtons() {
6 | return (
7 |
8 |
16 |
17 |
25 |
26 | );
27 | }
28 |
--------------------------------------------------------------------------------
/examples/e2e/app-pages-router/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # next.js
12 | /.next/
13 | .open-next
14 | /out/
15 |
16 | # production
17 | /build
18 |
19 | # misc
20 | .DS_Store
21 | *.pem
22 |
23 | # debug
24 | npm-debug.log*
25 | yarn-debug.log*
26 | yarn-error.log*
27 |
28 | # local env files
29 | .env*.local
30 |
31 | # vercel
32 | .vercel
33 |
34 | # typescript
35 | *.tsbuildinfo
36 | next-env.d.ts
37 |
38 | # playwright
39 | /test-results/
40 | /playwright-report/
41 | /blob-report/
42 | /playwright/.cache/
--------------------------------------------------------------------------------
/examples/middleware/app/middleware/page.tsx:
--------------------------------------------------------------------------------
1 | import { headers } from "next/headers";
2 |
3 | export default async function MiddlewarePage() {
4 | const cloudflareContextHeader = (await headers()).get("x-cloudflare-context");
5 |
6 | return (
7 | <>
8 | Via middleware
9 |
10 | The value of the x-cloudflare-context header is:
11 |
20 | {cloudflareContextHeader}
21 |
22 |
23 | >
24 | );
25 | }
26 |
--------------------------------------------------------------------------------
/examples/next-partial-prerendering/components/product-estimated-arrival.tsx:
--------------------------------------------------------------------------------
1 | import { add, format, isTomorrow } from 'date-fns';
2 |
3 | export const ProductEstimatedArrival = ({
4 | leadTime,
5 | hasDeliveryTime = false,
6 | }: {
7 | leadTime: number;
8 | hasDeliveryTime?: boolean;
9 | }) => {
10 | const date = add(new Date(), {
11 | days: leadTime,
12 | });
13 |
14 | return (
15 |
16 | Get it{' '}
17 |
18 | {isTomorrow(date) ? 'tomorrow, ' : null}
19 | {format(date, 'MMM d')}
20 |
21 | {hasDeliveryTime ? <> by 5pm> : null}
22 |
23 | );
24 | };
25 |
--------------------------------------------------------------------------------
/examples/overrides/kv-tag-next/wrangler.e2e.jsonc:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "node_modules/wrangler/config-schema.json",
3 | "main": ".open-next/worker.js",
4 | "name": "ssg-app",
5 | "compatibility_date": "2025-02-04",
6 | "compatibility_flags": ["nodejs_compat", "global_fetch_strictly_public"],
7 | "assets": {
8 | "directory": ".open-next/assets",
9 | "binding": "ASSETS",
10 | },
11 | "vars": {
12 | "APP_VERSION": "1.2.345",
13 | },
14 | "kv_namespaces": [
15 | {
16 | "binding": "NEXT_INC_CACHE_KV",
17 | "id": "INC-CACHE",
18 | "preview_id": "",
19 | },
20 | {
21 | "binding": "NEXT_TAG_CACHE_KV",
22 | "id": "TAG-CACHE",
23 | },
24 | ],
25 | }
26 |
--------------------------------------------------------------------------------
/examples/e2e/app-router/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # next.js
12 | /.next/
13 | .open-next
14 | /out/
15 |
16 | # production
17 | /build
18 |
19 | # misc
20 | .DS_Store
21 | *.pem
22 |
23 | # debug
24 | npm-debug.log*
25 | yarn-debug.log*
26 | yarn-error.log*
27 |
28 | # local env files
29 | .env*.local
30 |
31 | # vercel
32 | .vercel
33 |
34 | # typescript
35 | *.tsbuildinfo
36 | next-env.d.ts
37 |
38 | # playwright
39 | /test-results/
40 | /playwright-report/
41 | /blob-report/
42 | /playwright/.cache/
43 |
44 |
--------------------------------------------------------------------------------
/examples/e2e/experimental/src/app/use-cache/fetch/page.tsx:
--------------------------------------------------------------------------------
1 | import { ISRComponent } from "@/components/cached";
2 | import { Suspense } from "react";
3 |
4 | async function getFromFetch() {
5 | "use cache";
6 | // This is a simple fetch to ensure that the cache is working with IO inside
7 | const res = await fetch("https://opennext.js.org");
8 | return res.headers.get("Date");
9 | }
10 |
11 | export default async function Page() {
12 | const date = await getFromFetch();
13 | return (
14 |
15 |
Cache
16 |
{date}
17 |
Loading...}>
18 |
19 |
20 |
21 | );
22 | }
23 |
--------------------------------------------------------------------------------
/examples/next-partial-prerendering/components/product-split-payments.tsx:
--------------------------------------------------------------------------------
1 | import { ProductCurrencySymbol } from '#/components/product-currency-symbol';
2 | import { allocate, toUnit, up, type Dinero } from 'dinero.js';
3 |
4 | export const ProductSplitPayments = ({ price }: { price: Dinero }) => {
5 | // only offer split payments for more expensive items
6 | if (toUnit(price) < 150) {
7 | return null;
8 | }
9 |
10 | const [perMonth] = allocate(price, [1, 2]);
11 | return (
12 |
13 | Or
14 | {toUnit(perMonth, { digits: 0, round: up })}/month for 3 months
15 |
16 | );
17 | };
18 |
--------------------------------------------------------------------------------
/examples/playground15/open-next.config.ts:
--------------------------------------------------------------------------------
1 | import { defineCloudflareConfig, type OpenNextConfig } from "@opennextjs/cloudflare";
2 | import r2IncrementalCache from "@opennextjs/cloudflare/overrides/incremental-cache/r2-incremental-cache";
3 | import doQueue from "@opennextjs/cloudflare/overrides/queue/do-queue";
4 | import d1NextTagCache from "@opennextjs/cloudflare/overrides/tag-cache/d1-next-tag-cache";
5 |
6 | export default {
7 | ...defineCloudflareConfig({
8 | incrementalCache: r2IncrementalCache,
9 | queue: doQueue,
10 | tagCache: d1NextTagCache,
11 | }),
12 | cloudflare: {
13 | skewProtection: {
14 | enabled: false,
15 | },
16 | },
17 | } satisfies OpenNextConfig;
18 |
--------------------------------------------------------------------------------
/examples/ssg-app/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2017",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "strict": true,
8 | "noEmit": true,
9 | "esModuleInterop": true,
10 | "module": "esnext",
11 | "moduleResolution": "bundler",
12 | "resolveJsonModule": true,
13 | "isolatedModules": true,
14 | "jsx": "preserve",
15 | "incremental": true,
16 | "plugins": [
17 | {
18 | "name": "next"
19 | }
20 | ],
21 | "paths": {
22 | "@/*": ["./*"]
23 | }
24 | },
25 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
26 | "exclude": ["node_modules"]
27 | }
28 |
--------------------------------------------------------------------------------
/examples/middleware/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 | .yarn/install-state.gz
8 |
9 | # testing
10 | /coverage
11 |
12 | # next.js
13 | /.next/
14 | /out/
15 |
16 | # production
17 | /build
18 |
19 | # misc
20 | .DS_Store
21 | *.pem
22 |
23 | # debug
24 | npm-debug.log*
25 | yarn-debug.log*
26 | yarn-error.log*
27 |
28 | # local env files
29 | .env*.local
30 |
31 | # vercel
32 | .vercel
33 |
34 | # typescript
35 | *.tsbuildinfo
36 | next-env.d.ts
37 |
38 | # playwright
39 | /test-results/
40 | /playwright-report/
41 | /blob-report/
42 | /playwright/.cache/
43 |
--------------------------------------------------------------------------------
/create-cloudflare/next/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es2024",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "strict": true,
8 | "noEmit": true,
9 | "esModuleInterop": true,
10 | "module": "esnext",
11 | "moduleResolution": "bundler",
12 | "resolveJsonModule": true,
13 | "isolatedModules": true,
14 | "jsx": "preserve",
15 | "incremental": true,
16 | "plugins": [
17 | {
18 | "name": "next"
19 | }
20 | ],
21 | "paths": {
22 | "@/*": ["./src/*"]
23 | }
24 | },
25 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
26 | "exclude": ["node_modules"]
27 | }
28 |
--------------------------------------------------------------------------------
/examples/e2e/pages-router/src/pages/fallback/[slug].tsx:
--------------------------------------------------------------------------------
1 | import type { InferGetStaticPropsType } from "next";
2 |
3 | export function getStaticPaths() {
4 | return {
5 | paths: [
6 | {
7 | params: {
8 | slug: "fallback",
9 | },
10 | },
11 | ],
12 | fallback: false,
13 | };
14 | }
15 |
16 | export function getStaticProps() {
17 | return {
18 | props: {
19 | message: "This is a static fallback page.",
20 | },
21 | };
22 | }
23 |
24 | export default function Page({ message }: InferGetStaticPropsType) {
25 | return (
26 |
27 |
Static Fallback Page
28 |
{message}
29 |
30 | );
31 | }
32 |
--------------------------------------------------------------------------------
/examples/e2e/pages-router/wrangler.jsonc:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "node_modules/wrangler/config-schema.json",
3 | "main": ".open-next/worker.js",
4 | "name": "pages-router",
5 | "compatibility_date": "2024-12-30",
6 | "compatibility_flags": ["nodejs_compat", "global_fetch_strictly_public"],
7 | "assets": {
8 | "directory": ".open-next/assets",
9 | "binding": "ASSETS"
10 | },
11 | "r2_buckets": [
12 | {
13 | "binding": "NEXT_INC_CACHE_R2_BUCKET",
14 | "bucket_name": "cache"
15 | }
16 | ],
17 | "services": [
18 | {
19 | "binding": "WORKER_SELF_REFERENCE",
20 | "service": "pages-router"
21 | }
22 | ],
23 | "vars": {
24 | "OPEN_NEXT_REQUEST_ID_HEADER": "true"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/examples/playground14/app/api/hello/route.ts:
--------------------------------------------------------------------------------
1 | import { headers } from "next/headers";
2 |
3 | import { getCloudflareContext } from "@opennextjs/cloudflare";
4 |
5 | export async function GET() {
6 | const headersList = headers();
7 |
8 | const fromCloudflareContext = headersList.has("from-cloudflare-context");
9 |
10 | if (!fromCloudflareContext) {
11 | return new Response("Hello World!");
12 | }
13 |
14 | // Retrieve the bindings defined in wrangler.json
15 | return new Response(getCloudflareContext().env.hello);
16 | }
17 |
18 | export async function POST(request: Request) {
19 | const text = await request.text();
20 | return new Response(`Hello post-World! body=${text}`);
21 | }
22 |
--------------------------------------------------------------------------------
/examples/e2e/experimental/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2017",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "strict": true,
8 | "noEmit": true,
9 | "esModuleInterop": true,
10 | "module": "esnext",
11 | "moduleResolution": "bundler",
12 | "resolveJsonModule": true,
13 | "isolatedModules": true,
14 | "jsx": "preserve",
15 | "incremental": true,
16 | "plugins": [
17 | {
18 | "name": "next"
19 | }
20 | ],
21 | "paths": {
22 | "@/*": ["./src/*"]
23 | }
24 | },
25 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
26 | "exclude": ["node_modules"]
27 | }
28 |
--------------------------------------------------------------------------------
/examples/playground15/app/api/hello/route.ts:
--------------------------------------------------------------------------------
1 | import { headers } from "next/headers";
2 |
3 | import { getCloudflareContext } from "@opennextjs/cloudflare";
4 |
5 | export async function GET() {
6 | const headersList = await headers();
7 |
8 | const fromCloudflareContext = headersList.has("from-cloudflare-context");
9 |
10 | if (!fromCloudflareContext) {
11 | return new Response("Hello World!");
12 | }
13 |
14 | // Retrieve the bindings defined in wrangler.json
15 | return new Response(getCloudflareContext().env.hello);
16 | }
17 |
18 | export async function POST(request: Request) {
19 | const text = await request.text();
20 | return new Response(`Hello post-World! body=${text}`);
21 | }
22 |
--------------------------------------------------------------------------------
/examples/vercel-blog-starter/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "lib": ["dom", "dom.iterable", "esnext"],
4 | "allowJs": true,
5 | "skipLibCheck": true,
6 | "strict": true,
7 | "noEmit": true,
8 | "esModuleInterop": true,
9 | "module": "esnext",
10 | "moduleResolution": "bundler",
11 | "resolveJsonModule": true,
12 | "isolatedModules": true,
13 | "jsx": "preserve",
14 | "incremental": true,
15 | "plugins": [
16 | {
17 | "name": "next"
18 | }
19 | ],
20 | "paths": {
21 | "@/*": ["./src/*"]
22 | }
23 | },
24 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
25 | "exclude": ["node_modules", "open-next.config.ts"]
26 | }
27 |
--------------------------------------------------------------------------------
/examples/e2e/pages-router/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # next.js
12 | /.next/
13 | .open-next
14 | /out/
15 |
16 | # production
17 | /build
18 |
19 | # misc
20 | .DS_Store
21 | *.pem
22 |
23 | # debug
24 | npm-debug.log*
25 | yarn-debug.log*
26 | yarn-error.log*
27 | .pnpm-debug.log*
28 |
29 | # local env files
30 | .env*.local
31 |
32 | # vercel
33 | .vercel
34 |
35 | # typescript
36 | *.tsbuildinfo
37 | next-env.d.ts
38 |
39 | # playwright
40 | /test-results/
41 | /playwright-report/
42 | /blob-report/
43 | /playwright/.cache/
44 |
--------------------------------------------------------------------------------
/examples/e2e/pages-router/src/pages/fallback-intercepted/[slug].tsx:
--------------------------------------------------------------------------------
1 | import type { InferGetStaticPropsType } from "next";
2 |
3 | export function getStaticPaths() {
4 | return {
5 | paths: [
6 | {
7 | params: {
8 | slug: "fallback",
9 | },
10 | },
11 | ],
12 | fallback: false,
13 | };
14 | }
15 |
16 | export function getStaticProps() {
17 | return {
18 | props: {
19 | message: "This is a static fallback page.",
20 | },
21 | };
22 | }
23 |
24 | export default function Page({ message }: InferGetStaticPropsType) {
25 | return (
26 |
27 |
Static Fallback Page
28 |
{message}
29 |
30 | );
31 | }
32 |
--------------------------------------------------------------------------------
/examples/playground14/wrangler.jsonc:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "node_modules/wrangler/config-schema.json",
3 | "main": "worker.ts",
4 | "name": "playground14",
5 | "compatibility_date": "2024-12-30",
6 | "compatibility_flags": ["nodejs_compat", "global_fetch_strictly_public"],
7 | "assets": {
8 | "directory": ".open-next/assets",
9 | "binding": "ASSETS"
10 | },
11 | "kv_namespaces": [
12 | {
13 | "binding": "NEXT_INC_CACHE_KV",
14 | "id": ""
15 | }
16 | ],
17 | "vars": {
18 | "hello": "Hello World from the cloudflare context!",
19 | "PROCESS_ENV_VAR": "process.env",
20 | "NEXT_INC_CACHE_KV_PREFIX": "custom_prefix"
21 | },
22 | "images": {
23 | "binding": "IMAGES"
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/examples/bugs/gh-119/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2017",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "strict": true,
8 | "noEmit": true,
9 | "esModuleInterop": true,
10 | "module": "esnext",
11 | "moduleResolution": "bundler",
12 | "resolveJsonModule": true,
13 | "isolatedModules": true,
14 | "jsx": "preserve",
15 | "incremental": true,
16 | "plugins": [
17 | {
18 | "name": "next"
19 | }
20 | ],
21 | "paths": {
22 | "@/*": ["./*"]
23 | }
24 | },
25 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
26 | "exclude": ["node_modules", "open-next.config.ts"]
27 | }
28 |
--------------------------------------------------------------------------------
/examples/e2e/app-pages-router/wrangler.jsonc:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "node_modules/wrangler/config-schema.json",
3 | "main": ".open-next/worker.js",
4 | "name": "app-pages-router",
5 | "compatibility_date": "2024-12-30",
6 | "compatibility_flags": ["nodejs_compat", "global_fetch_strictly_public"],
7 | "assets": {
8 | "directory": ".open-next/assets",
9 | "binding": "ASSETS"
10 | },
11 | "r2_buckets": [
12 | {
13 | "binding": "NEXT_INC_CACHE_R2_BUCKET",
14 | "bucket_name": "cache"
15 | }
16 | ],
17 | "services": [
18 | {
19 | "binding": "WORKER_SELF_REFERENCE",
20 | "service": "app-pages-router"
21 | }
22 | ],
23 | "vars": {
24 | "NEXT_INC_CACHE_R2_PREFIX": "custom_prefix"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/examples/e2e/app-router/app/ssr/page.tsx:
--------------------------------------------------------------------------------
1 | import { headers } from "next/headers";
2 |
3 | async function getTime() {
4 | const res = await new Promise((resolve) => {
5 | setTimeout(() => {
6 | resolve(new Date().toISOString());
7 | }, 1500);
8 | });
9 | return res;
10 | }
11 |
12 | export default async function SSR() {
13 | const time = await getTime();
14 | const headerList = await headers();
15 | const responseOpenNext = await fetch("https://opennext.js.org", {
16 | cache: "force-cache",
17 | });
18 | return (
19 |
20 |
Time: {time}
21 |
{headerList.get("host")}
22 |
Cached fetch: {responseOpenNext.headers.get("date")}
23 |
24 | );
25 | }
26 |
--------------------------------------------------------------------------------
/examples/playground14/worker.ts:
--------------------------------------------------------------------------------
1 | // @ts-ignore `.open-next/worker.ts` is generated at build time
2 | import { default as handler } from "./.open-next/worker.js";
3 |
4 | export default {
5 | fetch: handler.fetch,
6 |
7 | /**
8 | * Scheduled Handler
9 | *
10 | * Can be tested with:
11 | * - `wrangler dev --test-scheduled`
12 | * - `curl "http://localhost:8787/__scheduled?cron=*+*+*+*+*"`
13 | * @param event
14 | */
15 | async scheduled(event) {
16 | console.log("Scheduled event", event);
17 | },
18 | } satisfies ExportedHandler;
19 |
20 | // @ts-ignore `.open-next/worker.ts` is generated at build time
21 | export { DOQueueHandler, DOShardedTagCache } from "./.open-next/worker.js";
22 |
--------------------------------------------------------------------------------
/examples/bugs/gh-219/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2017",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "strict": true,
8 | "noEmit": true,
9 | "esModuleInterop": true,
10 | "module": "esnext",
11 | "moduleResolution": "bundler",
12 | "resolveJsonModule": true,
13 | "isolatedModules": true,
14 | "jsx": "preserve",
15 | "incremental": true,
16 | "plugins": [
17 | {
18 | "name": "next"
19 | }
20 | ],
21 | "paths": {
22 | "@/*": ["./src/*"]
23 | }
24 | },
25 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
26 | "exclude": ["node_modules", "open-next.config.ts"]
27 | }
28 |
--------------------------------------------------------------------------------
/examples/bugs/gh-223/app/globals.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
5 | :root {
6 | --foreground-rgb: 0, 0, 0;
7 | --background-start-rgb: 214, 219, 220;
8 | --background-end-rgb: 255, 255, 255;
9 | }
10 |
11 | @media (prefers-color-scheme: dark) {
12 | :root {
13 | --foreground-rgb: 255, 255, 255;
14 | --background-start-rgb: 0, 0, 0;
15 | --background-end-rgb: 0, 0, 0;
16 | }
17 | }
18 |
19 | body {
20 | color: rgb(var(--foreground-rgb));
21 | background: linear-gradient(to bottom, transparent, rgb(var(--background-end-rgb)))
22 | rgb(var(--background-start-rgb));
23 | }
24 |
25 | @layer utilities {
26 | .text-balance {
27 | text-wrap: balance;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/examples/create-next-app/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "lib": ["dom", "dom.iterable", "esnext"],
4 | "allowJs": true,
5 | "skipLibCheck": true,
6 | "strict": true,
7 | "noEmit": true,
8 | "esModuleInterop": true,
9 | "module": "esnext",
10 | "moduleResolution": "bundler",
11 | "resolveJsonModule": true,
12 | "isolatedModules": true,
13 | "jsx": "preserve",
14 | "incremental": true,
15 | "plugins": [
16 | {
17 | "name": "next"
18 | }
19 | ],
20 | "paths": {
21 | "@/*": ["./src/*"]
22 | },
23 | "target": "ES2017"
24 | },
25 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
26 | "exclude": ["node_modules", "open-next.config.ts"]
27 | }
28 |
--------------------------------------------------------------------------------
/examples/middleware/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "strict": true,
8 | "forceConsistentCasingInFileNames": true,
9 | "noEmit": true,
10 | "esModuleInterop": true,
11 | "module": "esnext",
12 | "moduleResolution": "node",
13 | "resolveJsonModule": true,
14 | "isolatedModules": true,
15 | "jsx": "preserve",
16 | "incremental": true,
17 | "plugins": [
18 | {
19 | "name": "next"
20 | }
21 | ]
22 | },
23 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
24 | "exclude": ["node_modules", "open-next.config.ts", "worker.ts"]
25 | }
26 |
--------------------------------------------------------------------------------
/examples/next-partial-prerendering/components/product-review-card.tsx:
--------------------------------------------------------------------------------
1 | import type { Review } from '#/types/review';
2 | import { ProductRating } from '#/components/product-rating';
3 |
4 | export const ProductReviewCard = ({ review }: { review: Review }) => {
5 | return (
6 |
7 |
8 |
9 |
10 |
{review.name}
11 |
12 |
13 | {review.rating ?
: null}
14 |
15 |
16 |
{review.text}
17 |
18 | );
19 | };
20 |
--------------------------------------------------------------------------------
/examples/playground15/app/from-app/page.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import Link from "next/link";
4 | import Image from "next/image";
5 | import testImage from "../../public/test.jpg";
6 |
7 | export default function Page() {
8 | return (
9 | <>
10 | hello app
11 |
12 | {process.env.NEXT_DEPLOYMENT_ID}
13 |
14 |
24 |
25 | other app
26 |
27 | >
28 | );
29 | }
30 |
--------------------------------------------------------------------------------
/examples/prisma/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2017",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "strict": true,
8 | "noEmit": true,
9 | "esModuleInterop": true,
10 | "module": "esnext",
11 | "moduleResolution": "bundler",
12 | "resolveJsonModule": true,
13 | "isolatedModules": true,
14 | "jsx": "react-jsx",
15 | "incremental": true,
16 | "plugins": [
17 | {
18 | "name": "next"
19 | }
20 | ],
21 | "paths": {
22 | "@/*": ["./src/*"]
23 | }
24 | },
25 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", ".next/dev/types/**/*.ts"],
26 | "exclude": ["node_modules"]
27 | }
28 |
--------------------------------------------------------------------------------
/packages/cloudflare/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json.schemastore.org/tsconfig",
3 | "extends": "@tsconfig/strictest/tsconfig.json",
4 | "compilerOptions": {
5 | "declaration": true,
6 | "esModuleInterop": true,
7 | "exactOptionalPropertyTypes": false,
8 | "forceConsistentCasingInFileNames": true,
9 | "lib": ["ESNext"],
10 | "module": "ESNext",
11 | "moduleResolution": "node",
12 | "noImplicitReturns": false,
13 | "noPropertyAccessFromIndexSignature": false,
14 | "outDir": "./dist",
15 | "target": "ES2022",
16 | "types": ["@cloudflare/workers-types", "@opennextjs/aws/types/global.d.ts"]
17 | },
18 | "include": ["src/**/*.ts", "env.d.ts"],
19 | "exclude": ["src/**/*.spec.ts"]
20 | }
21 |
--------------------------------------------------------------------------------
/examples/playground14/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "lib": ["dom", "dom.iterable", "esnext"],
4 | "allowJs": true,
5 | "skipLibCheck": true,
6 | "strict": false,
7 | "noEmit": true,
8 | "incremental": true,
9 | "module": "esnext",
10 | "esModuleInterop": true,
11 | "moduleResolution": "node",
12 | "resolveJsonModule": true,
13 | "isolatedModules": true,
14 | "jsx": "preserve",
15 | "plugins": [
16 | {
17 | "name": "next"
18 | }
19 | ],
20 | "strictNullChecks": true,
21 | "target": "ES2017"
22 | },
23 | "include": ["next-env.d.ts", ".next/types/**/*.ts", "**/*.ts", "**/*.tsx", "worker-configuration.d.ts"],
24 | "exclude": ["node_modules", "open-next.config.ts"]
25 | }
26 |
--------------------------------------------------------------------------------
/examples/playground15/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "lib": ["dom", "dom.iterable", "esnext"],
4 | "allowJs": true,
5 | "skipLibCheck": true,
6 | "strict": false,
7 | "noEmit": true,
8 | "incremental": true,
9 | "module": "esnext",
10 | "esModuleInterop": true,
11 | "moduleResolution": "node",
12 | "resolveJsonModule": true,
13 | "isolatedModules": true,
14 | "jsx": "preserve",
15 | "plugins": [
16 | {
17 | "name": "next"
18 | }
19 | ],
20 | "target": "ES2017",
21 | "strictNullChecks": true
22 | },
23 | "include": ["next-env.d.ts", ".next/types/**/*.ts", "**/*.ts", "**/*.tsx", "worker-configuration.d.ts"],
24 | "exclude": ["node_modules", "open-next.config.ts"]
25 | }
26 |
--------------------------------------------------------------------------------
/examples/vercel-blog-starter/src/app/_components/intro.tsx:
--------------------------------------------------------------------------------
1 | import { CMS_NAME } from "@/lib/constants";
2 |
3 | export function Intro() {
4 | return (
5 |
6 | Blog.
7 |
8 | A statically generated blog example using{" "}
9 |
13 | Next.js
14 | {" "}
15 | and {CMS_NAME}.
16 |
17 |
18 | );
19 | }
20 |
--------------------------------------------------------------------------------
/examples/create-next-app/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 | .yarn/install-state.gz
8 |
9 | # testing
10 | /coverage
11 |
12 | # next.js
13 | /.next/
14 | /out/
15 |
16 | # production
17 | /build
18 |
19 | # misc
20 | .DS_Store
21 | *.pem
22 |
23 | # debug
24 | npm-debug.log*
25 | yarn-debug.log*
26 | yarn-error.log*
27 |
28 | # local env files
29 | .env*.local
30 |
31 | # vercel
32 | .vercel
33 |
34 | # typescript
35 | *.tsbuildinfo
36 | next-env.d.ts
37 |
38 | # wrangler
39 | .wrangler
40 |
41 | # playwright
42 | /test-results/
43 | /playwright-report/
44 | /blob-report/
45 | /playwright/.cache/
46 |
--------------------------------------------------------------------------------
/examples/e2e/app-pages-router/e2e/middleware.test.ts:
--------------------------------------------------------------------------------
1 | import { expect, test } from "@playwright/test";
2 |
3 | test("should return correctly on HEAD request with an empty body", async ({ request }) => {
4 | const response = await request.head("/head");
5 | expect(response.status()).toBe(200);
6 | const body = await response.text();
7 | expect(body).toBe("");
8 | expect(response.headers()["x-from-middleware"]).toBe("true");
9 | });
10 |
11 | test("should return correctly for directly returning a fetch response", async ({ request }) => {
12 | const response = await request.get("/fetch");
13 | expect(response.status()).toBe(200);
14 | const body = await response.json();
15 | expect(body).toEqual({ hello: "world" });
16 | });
17 |
--------------------------------------------------------------------------------
/examples/overrides/d1-tag-next/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2017",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "strict": true,
8 | "noEmit": true,
9 | "esModuleInterop": true,
10 | "module": "esnext",
11 | "moduleResolution": "bundler",
12 | "resolveJsonModule": true,
13 | "isolatedModules": true,
14 | "jsx": "react-jsx",
15 | "incremental": true,
16 | "plugins": [
17 | {
18 | "name": "next"
19 | }
20 | ],
21 | "paths": {
22 | "@/*": ["./*"]
23 | }
24 | },
25 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", ".next/dev/types/**/*.ts"],
26 | "exclude": ["node_modules"]
27 | }
28 |
--------------------------------------------------------------------------------
/examples/overrides/kv-tag-next/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2017",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "strict": true,
8 | "noEmit": true,
9 | "esModuleInterop": true,
10 | "module": "esnext",
11 | "moduleResolution": "bundler",
12 | "resolveJsonModule": true,
13 | "isolatedModules": true,
14 | "jsx": "react-jsx",
15 | "incremental": true,
16 | "plugins": [
17 | {
18 | "name": "next"
19 | }
20 | ],
21 | "paths": {
22 | "@/*": ["./*"]
23 | }
24 | },
25 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", ".next/dev/types/**/*.ts"],
26 | "exclude": ["node_modules"]
27 | }
28 |
--------------------------------------------------------------------------------
/examples/overrides/memory-queue/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2017",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "strict": true,
8 | "noEmit": true,
9 | "esModuleInterop": true,
10 | "module": "esnext",
11 | "moduleResolution": "bundler",
12 | "resolveJsonModule": true,
13 | "isolatedModules": true,
14 | "jsx": "react-jsx",
15 | "incremental": true,
16 | "plugins": [
17 | {
18 | "name": "next"
19 | }
20 | ],
21 | "paths": {
22 | "@/*": ["./*"]
23 | }
24 | },
25 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", ".next/dev/types/**/*.ts"],
26 | "exclude": ["node_modules"]
27 | }
28 |
--------------------------------------------------------------------------------
/examples/playground14/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 | .yarn/install-state.gz
8 |
9 | # testing
10 | /coverage
11 |
12 | # next.js
13 | /.next/
14 | /out/
15 |
16 | # production
17 | /build
18 |
19 | # misc
20 | .DS_Store
21 | *.pem
22 |
23 | # debug
24 | npm-debug.log*
25 | yarn-debug.log*
26 | yarn-error.log*
27 |
28 | # local env files
29 | .env*.local
30 |
31 | # vercel
32 | .vercel
33 |
34 | # typescript
35 | *.tsbuildinfo
36 | next-env.d.ts
37 |
38 | # wrangler
39 | .wrangler
40 |
41 | # playwright
42 | /test-results/
43 | /playwright-report/
44 | /blob-report/
45 | /playwright/.cache/
46 |
--------------------------------------------------------------------------------
/examples/playground15/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 | .yarn/install-state.gz
8 |
9 | # testing
10 | /coverage
11 |
12 | # next.js
13 | /.next/
14 | /out/
15 |
16 | # production
17 | /build
18 |
19 | # misc
20 | .DS_Store
21 | *.pem
22 |
23 | # debug
24 | npm-debug.log*
25 | yarn-debug.log*
26 | yarn-error.log*
27 |
28 | # local env files
29 | .env*.local
30 |
31 | # vercel
32 | .vercel
33 |
34 | # typescript
35 | *.tsbuildinfo
36 | next-env.d.ts
37 |
38 | # wrangler
39 | .wrangler
40 |
41 | # playwright
42 | /test-results/
43 | /playwright-report/
44 | /blob-report/
45 | /playwright/.cache/
46 |
--------------------------------------------------------------------------------
/examples/e2e/pages-router/e2e/header.test.ts:
--------------------------------------------------------------------------------
1 | import { expect, test } from "@playwright/test";
2 |
3 | test("should test if poweredByHeader adds the correct headers ", async ({ page }) => {
4 | const result = await page.goto("/");
5 | expect(result).toBeDefined();
6 | expect(result?.status()).toBe(200);
7 | const headers = result?.headers();
8 |
9 | // Both these headers should be present cause poweredByHeader is true in pagesRouter
10 | expect(headers?.["x-powered-by"]).toBe("Next.js");
11 | expect(headers?.["x-opennext"]).toBe("1");
12 | // This header should be defined cause we have set the `OPEN_NEXT_REQUEST_ID_HEADER` env variable in wrangler.jsonc
13 | expect(headers?.["x-opennext-requestid"]).not.toBeUndefined();
14 | });
15 |
--------------------------------------------------------------------------------
/examples/ssg-app/app/layout.tsx:
--------------------------------------------------------------------------------
1 | import type { Metadata } from "next";
2 | import "./globals.css";
3 |
4 | import { getCloudflareContext } from "@opennextjs/cloudflare";
5 |
6 | export const metadata: Metadata = {
7 | title: "SSG App",
8 | description: "An app in which all the routes are SSG'd",
9 | };
10 |
11 | export default async function RootLayout({
12 | children,
13 | }: Readonly<{
14 | children: React.ReactNode;
15 | }>) {
16 | const cloudflareContext = await getCloudflareContext({
17 | async: true,
18 | });
19 |
20 | return (
21 |
22 |
23 | {children}
24 |
25 |
26 |
27 | );
28 | }
29 |
--------------------------------------------------------------------------------