Skip to content

Commit 826a37e

Browse files
authored
Docs for V3 (#400)
* moved old docs to V2 * removed V3 folder * base V3 docs * wip * mostly final docs
1 parent 3990502 commit 826a37e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+869
-248
lines changed

Diff for: docs/pages/_meta.json

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
{
22
"index": "Home",
33
"get_started": "Getting started",
4-
"common_issues": "Common issues",
4+
"config": "Configuration",
5+
"comparison": "Comparison",
56
"inner_workings": "How does it work?",
6-
"advanced": "Advanced",
7-
"faq": "FAQ"
7+
"faq": "FAQ",
8+
"common_issues": "Troubleshooting",
9+
"contribute": "Contributing"
810
}

Diff for: docs/pages/common_issues.mdx

+33-14
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,42 @@
1-
#### Cannot find module next
1+
#### Debug mode
2+
3+
OpenNext can be executed in debug mode by setting the environment variable `OPEN_NEXT_DEBUG=true`.
24

3-
You might stumble upon this error inside cloudwatch logs: `Cannot find module 'next'`.
4-
It is likely that you are in a monorepo and you have several lock files.
5-
Just make sure that you have a single lock file in the root of your project.
5+
This will output **A LOT** of additional logs to the console.This also disable minifying in esbuild, and add source maps to the output. This can result in code that might be up to 2-3X larger than the production build. **Do not enable this in production**
66

7-
#### headers, redirect, rewrites in `next-config` and middleware are not working in next 13.4.12+
7+
```bash
8+
OPEN_NEXT_DEBUG=true npx open-next@latest build
9+
```
10+
11+
#### Cannot find module next
812

9-
If you use a version of nextjs >= 13.4.12, you'll need to use an open-next version >= 2.1
13+
You might stumble upon this error inside cloudwatch logs: `Cannot find module 'next'`. It is likely that you are in a monorepo and you have several lock files. **Just make sure that you have a single lock file in the root of your project.**
1014

11-
#### My api route are returning empty response and i'm using sentry
15+
#### Reducing bundle size
1216

13-
If you are using sentry, API routes returns empty body. You could try configuring sentry to ignore API routes. You can read more about it [here](https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/?opt-out-of-auto-instrumentation-on-specific-routes)
17+
Next might incorrectly include some dependencies in the bundle. To remove them you can use this configuration inside `next.config.js`:
1418

15-
#### My ISR page has this cache-control header `s-maxage=2, stale-while-revalidate=2592000`
19+
```javascript
20+
experimental: {
21+
outputFileTracingExcludes: {
22+
"*": ["node_modules/the-unwanted-package"],
23+
},
24+
},
25+
```
26+
Also you should not add sharp as a dependencies unless absolutely necessary, the image optimization already has it's own version of sharp.
1627

17-
Given how ISR works, while waiting for the revalidation to happen, the page will be served using this cache control header. This prevent your server from being overloaded by a lot of requests while the revalidation is done. You can read more about it [here](/inner_workings/isr).
28+
#### Patch fetch behaviour for ISR. Only for [email protected]+
1829

19-
#### Unzipped size must be smaller than 262144000 bytes
30+
If you use ISR and fetch in your app, you may encounter a bug that makes your revalidate values inconsistent.
31+
The issue is that it revalidates using the lowest revalidate of all fetch calls in your page, regardless of their individual values. To fix this bug, you need to modify the fetch function in your root layout component with the following code snippet
2032

21-
AWS Lambda has an unzipped size limit of 250MB. If your app is over this limit, then it is most likely using a node_module library that is too large for serverless or there is a large dev dependency getting bundled.
22-
For example, `pdfjs` has `canvas` optional dependency which takes up 180MB. For more details, [read me](/common_issues/bundle_size).
23-
Note: a large bundle size will increase cold start significantly.
33+
```ts
34+
export default function RootLayout() {
35+
const asyncStorage = require("next/dist/client/components/static-generation-async-storage.external");
36+
//@ts-ignore
37+
const staticStore = (fetch as any).__nextGetStaticStore?.() || asyncStorage.staticGenerationAsyncStorage;
38+
const store = staticStore.getStore();
39+
store.isOnDemandRevalidate = store.isOnDemandRevalidate && !(process.env.OPEN_NEXT_ISR === 'true');
40+
return <>...</>;
41+
}
42+
```

Diff for: docs/pages/comparison.mdx

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
It should be noted that open-next does not actually deploy the app. It only bundles everything for your IAC to deploy it.
2+
3+
Here is a table comparing the different options to deploy a next.js app:
4+
5+
| Features | OpenNext | Vercel | AWS Amplify | Docker Standalone |
6+
| --- | --- | --- | --- | --- |
7+
| **Function splitting** | Yes | Yes | No | No |
8+
| **Multiple deployment target** ¹ | Yes | Yes ² | No | No |
9+
| **Serverless** | Yes | Yes | Yes | No ³ |
10+
| **Warmer function** | Yes | No | No | Not necessary |
11+
| **External middleware** | Yes ⁴ | Yes | No | No |
12+
| **Edge runtime support** | Partial Support ⁵ | Yes | Embedded ⁶ | Embedded ⁶ |
13+
| **ISR** | Yes | Yes | Yes | Yes ⁷ |
14+
| **On-Demand Revalidation** | Yes ⁸ | Yes | No | Yes ⁸ |
15+
| **Custom server** | Yes ⁹ | No | No | Yes |
16+
17+
1. Multiple deployment target means that you can deploy the same app to different target like some part to ECS, some part to Lambda etc...
18+
2. Vercel supports only serverless Node (backed by AWS Lambda) and Edge runtime (backed by cloudflare workers)
19+
2. You can deploy a dockerized next.js app to AWS lambda using AWS Lambda Web adapter, but some part like ISR will not work as expected
20+
3. OpenNext supports external middleware, but it is not enabled by default.
21+
4. OpenNext supports edge runtime in node, but every route needs to be deployed separately. OpenNext supports edge runtime in cloudflare workers, but only for app router api routes.
22+
5. Embedded means that the edge runtime is embedded inside the bundle. It emulates a fake edge runtime inside the prod environment.
23+
6. You might experience some inconsistencies with ISR if you have a CDN in front of your app. Next always set the cache-control header to `s-maxage=REVALIDATION_TIME, stale-while-revalidate`, it means that your data (json or rsc) and your html might be out of sync.
24+
7. You need to invalidate the CDN manually. For OpenNext, here is an example for cloudfront
25+
8. OpenNext supports custom server, but it is not enabled by default. You can have a custom server even in a serverless environment.

Diff for: docs/pages/v3/config.mdx renamed to docs/pages/config.mdx

+48-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,18 @@
1-
Here is a simple example of an `open-next.config.ts` file:
1+
### Build Arguments
2+
3+
There is a single build argument that you can pass to the `open-next build` command:
4+
- `--config-path` - This is the path to the configuration file that you want to use. By default, it will look for `open-next.config.ts` in the current working directory. This needs to be relative to the current working directory.
5+
6+
### Configuration File
7+
8+
For personalisation you need to create a file `open-next.config.ts` at the same place as your `next.config.js`, and export a default object that satisfies the `OpenNextConfig` interface.
9+
10+
Here is a detailed example of an `open-next.config.ts` file:
211
This file need to be at the same place as your `next.config.js` file
312

413
`server` in here could refer to a lambda function, a docker container, a node server or whatever that can support running nodejs code. (Even cloudflare workers in the future)
514

6-
For more information about the options here, just look at the source file
15+
For more information about the options here, take a look at the [components section](/components/overview).
716

817
```ts
918
import type { OpenNextConfig } from 'open-next/types/open-next'
@@ -20,8 +29,10 @@ const config = {
2029
}
2130
})
2231
},
32+
minify: true, // This will minify the output
2333
},
2434
// Below we define the functions that we want to deploy in a different server
35+
// This is only used if you want to split the server into multiple servers
2536
functions: {
2637
ssr: {
2738
routes: [
@@ -33,15 +44,19 @@ const config = {
3344
override: {
3445
wrapper: "aws-lambda-streaming",
3546
},
36-
experimentalBundledNextServer: true // This enables the bundled next server which is faster and reduce the size of the server
47+
// This enables the bundled next server which is faster and reduce the size of the server
48+
// This is also experimental and might not work in all cases
49+
experimentalBundledNextServer: true
3750
},
3851
pageSsr: {
3952
routes: ["pages/pageSsr"], // For page dir routes should be in the form `pages/${route}` without the extension, it should match the filesystem
53+
// BUILD_ID is a special case, it will be replaced with the actual build id
4054
patterns: [ 'pageSsr', "_next/data/BUILD_ID/pageSsr.json"],
4155
override: {
4256
wrapper: "node",
4357
converter: "node",
4458
// This is necessary to generate the dockerfile and for the implementation to know that it needs to deploy on docker
59+
// You can also provide a string here which will be used to create the dockerfile
4560
generateDockerfile: true,
4661
},
4762
},
@@ -58,10 +73,40 @@ const config = {
5873
// It could be in lambda@edge, cloudflare workers, or anywhere else
5974
// By default it uses lambda@edge
6075
// This is not implemented in the reference construct implementation.
76+
// This is optional, but might be necessary if you split your app into multiple servers
6177
middleware: {
6278
external: true
6379
}
80+
81+
// Optional
82+
imageOptimization: {
83+
// This is the architecture of the image, it could be x64 or arm64
84+
// This is necessary to bundle the proper version of sharp
85+
arch: "x64",
86+
}
87+
88+
// If you want to override the default build command, you can do it here
89+
// By default it uses `npm run build`
6490
buildCommand: "echo 'hello world'",
91+
92+
dangerous: {
93+
// This will disable the tag cache
94+
// You can use it safely on page router, on app router it will break revalidateTag and revalidatePath
95+
disableTagCache: true,
96+
// This will disable the incremental cache
97+
// This is generally not recommended, as this is necessary for ISR AND SSG routes as well as the fetch cache
98+
disableIncrementalCache: true,
99+
}
100+
101+
//The path to the target folder of build output from the `buildCommand` option (the path which will contain the `.next` and `.open-next` folders). This path is relative from the current process.cwd() - Optional default to "."
102+
buildOutputPath: "build",
103+
104+
//The path to the root of the Next.js app's source code. This path is relative from the current process.cwd(). - Optional default to "."
105+
appPath: "app",
106+
107+
//The path to the package.json file of the Next.js app. This path is relative from the current process.cwd(). - Optional
108+
packageJsonPath: "package.json",
109+
65110
} satisfies OpenNextConfig
66111

67112
export default config;
File renamed without changes.

Diff for: docs/pages/contribute/plugin.mdx

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
OpenNext use 3 different esbuild plugins internally to recompile or modify the source code depending on some condition like the next version or the runtime used
2+
3+
#### OpenNext Replacement Plugin
4+
5+
This plugin is used to replace some code in the source code with some other code.
6+
7+
Here is a very simple example of how to use it:
8+
9+
```typescript
10+
openNextPlugin({
11+
// The target file to replace code in
12+
target: /plugins\/default\.js/g,
13+
// This is where the plugin will look for the code to replace
14+
replacements: [require.resolve("./plugins/default.js")],
15+
// This is to delete some code from the target file
16+
deletes: ["id1"],
17+
})
18+
19+
//To inject arbritary code by using (import at top of file):
20+
21+
//#import
22+
23+
import data from 'data'
24+
const datum = data.datum
25+
26+
//#endImport
27+
28+
To replace code:
29+
30+
//#override id1
31+
32+
export function overrideMe() {
33+
// I will replace the "id1" block in the target file
34+
}
35+
36+
//#endOverride
37+
```
38+
39+
#### OpenNext Resolve Plugin
40+
41+
This plugin is used to avoid having to bundle the whole library in the final bundle. It will replace the dynamic import of the overrides with the one that we want to use.
42+
43+
Here is a very simple example of how to use it:
44+
45+
```typescript
46+
openNextResolvePlugin({
47+
overrides: {
48+
wrapper: "node",
49+
converter: "node",
50+
}
51+
})
52+
```
53+
54+
#### OpenNext Edge Plugin
55+
56+
This plugin is used to properly compile routes or middleware built for the `edge` runtime.
57+
58+
Here is a very simple example of how to use it:
59+
60+
```typescript
61+
openNextEdgePlugin({
62+
// The path to the .next directory
63+
nextDir: "next",
64+
// The path to the edgeFunctionHandler.js file that we'll use to bundle the routing
65+
edgeFunctionHandlerPath: "./edgeFunctionHandler.js",
66+
// The middlewareInfo from the middlware manifest file
67+
middlewareInfo: middlewareInfo
68+
// If the app should be bundled for cloudflare workers
69+
isInCloudflare: true
70+
})
71+
```

Diff for: docs/pages/get_started.mdx

+6
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ The easiest way to deploy OpenNext to AWS is with [SST](https://docs.sst.dev/sta
1010

1111
For more information, check out the SST docs: https://docs.sst.dev/start/nextjs
1212

13+
### Ion
14+
15+
You can also deploy OpenNext to AWS using [Ion](https://ion.sst.dev/).
16+
17+
Check out the [Ion Docs](https://ion.sst.dev/docs/start/nextjs/)
18+
1319
### Other Frameworks
1420

1521
The OpenNext community has contributed deployment options for a few other frameworks.

Diff for: docs/pages/index.mdx

+19-8
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,31 @@
11
import {SITE} from "../config"
2+
import { Callout } from 'nextra/components'
23

3-
### Open source Next.js serverless adapter
4+
<Callout>
5+
This docs is for the V3 of OpenNext. If you are looking for the V2 docs, you can find them [here](/v2).
6+
7+
If you're migrating from V2 to V3, you can find the migration guide [here](/migration#from-opennext-v2).
8+
</Callout>
9+
10+
### Open source Next.js adapter
411

512
---
613

7-
OpenNext takes the Next.js build output and converts it into a package that can be deployed to any functions as a service platform. As of now only AWS Lambda is supported.
814

15+
OpenNext takes the Next.js build output and converts it into packages that can be deployed across a variety of environments.
16+
Natively OpenNext has support for AWS Lambda and classic Node Server. It also offer partial support for the `edge` runtime in Cloudflare Workers.
17+
18+
One notable feature of OpenNext is its ability to split the Next.js output, enabling selective deployment to different targets such as AWS Lambda, Cloudflare Workers, or Amazon ECS. This facilitates a tailored deployment strategy that aligns with the specific needs of your application.
19+
20+
Thanks to this, you could deploy part of your API to ECS, another part to Cloudflare Workers, your SSR routes to another ECS cluster, and your ISR/SSG routes to Lambda.
921

1022
---
1123

1224
While Vercel is great, it's not a good option if all your infrastructure is on AWS. Hosting it in your AWS account makes it easy to integrate with your backend. And it's a lot cheaper than Vercel.
1325

14-
Next.js, unlike Remix or Astro, doesn't have a way to self-host using serverless. You can run it as a Node application. This however doesn't work the same way as it does on Vercel.
26+
Vercel is also limited to serverless and to their way of doing things. OpenNext is open source and can be deployed to any platform that supports Node.js.
27+
28+
Next.js, unlike Remix or Astro, doesn't have a way to self-host using **serverless**. You can run it as a Node application. This however doesn't work the same way as it does on Vercel.
1529

1630
---
1731

@@ -23,10 +37,6 @@ Closed source SaaS products like [Amplify](https://aws.amazon.com/amplify/) have
2337

2438
---
2539

26-
The goal of OpenNext is to create an open source, framework agnostic, serverless adapter for Next.js.
27-
28-
OpenNext is currently built for AWS but we plan to support any functions as a service platform.
29-
3040
We need your help keeping it up to date and feature complete. Make sure to [**join us on Discord**](https://sst.dev/discord) and [**star us on GitHub**](https://github.com/sst/open-next).
3141
## Features
3242

@@ -48,4 +58,5 @@ OpenNext aims to support all Next.js 13 features. Some features are work in prog
4858
## Who is using OpenNext?
4959

5060
[NHS England](https://github.com/nhs-england-tools/terraform-aws-opennext),
51-
[Udacity](https://engineering.udacity.com/deploying-next-js-on-the-edge-with-sst-is-sst-the-game-changer-its-claimed-to-be-1f05a0abc27c)
61+
[Udacity](https://engineering.udacity.com/deploying-next-js-on-the-edge-with-sst-is-sst-the-game-changer-its-claimed-to-be-1f05a0abc27c)
62+
[Gymshark UK](https://uk.gymshark.com)

Diff for: docs/pages/inner_workings.mdx

+9-7
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,13 @@ The build output is then transformed into a format that can be deployed to AWS.
1111
```bash
1212
my-next-app/
1313
.open-next/
14-
cache/ -> ISR cache files to upload to an S3 Bucket
15-
assets/ -> Static files to upload to an S3 Bucket
16-
server-function/ -> Handler code for server Lambda Function
17-
revalidation-function/ -> Handler code for revalidation Lambda Function
18-
image-optimization-function/ -> Handler code for image optimization Lambda Function
19-
warmer-function/ -> Cron job code to keep server function warm
20-
dynamo-provider/ -> Code for a CDK custom resource to populate a DynamoDB table
14+
cache/ -> ISR cache files to upload - This cannot be directly served
15+
assets/ -> Static files to upload
16+
server-functions/
17+
default/ -> Handler code for the default server
18+
other-fn/ -> Handler code for another backend
19+
revalidation-function/ -> Handler code for revalidation backend
20+
image-optimization-function/ -> Handler code for image optimization backend
21+
warmer-function/ -> Cron job code to keep server function warm - Not mandatory
22+
dynamo-provider/ -> Code for a custom resource to populate the Tag Cache - Only necessary for app dir
2123
```

Diff for: docs/pages/inner_workings/_meta.json

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
{
2-
"isr": "ISR"
3-
}
2+
"caching": "Caching (ISR/SSG)",
3+
"components": "Main Components",
4+
"architecture": "Default Architecture"
5+
}

0 commit comments

Comments
 (0)