You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+33-22Lines changed: 33 additions & 22 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -128,40 +128,46 @@ Create a Lambda function using the code in the `.open-next/server-function` fold
128
128
This function handles all other types of requests from the Next.js app, including Server-side Rendering (SSR) requests and API requests. OpenNext builds the Next.js app in **standalone** mode. The standalone mode generates a `.next` folder containing the **NextServer** class that handles requests and a `node_modules` folder with **all the dependencies** needed to run the `NextServer`. The structure looks like this:
129
129
130
130
```
131
-
.next/ -> NextServer
132
-
node_modules/ -> dependencies
131
+
.next/ -> NextServer
132
+
node_modules/ -> dependencies
133
133
```
134
134
135
135
The server function adapter wraps around `NextServer` and exports a handler function that supports the Lambda request and response. The `server-function` bundle looks like this:
136
136
137
137
```diff
138
-
.next/ -> NextServer
139
-
node_modules/ -> dependencies
140
-
+ index.mjs -> server function adapter
138
+
.next/ -> NextServer
139
+
+ .open-next/
140
+
+ public-files.json -> `/public` file listing
141
+
node_modules/ -> dependencies
142
+
+ index.mjs -> server function adapter
141
143
```
142
144
145
+
The file `public-files.json` contains the top-level file and directory names in your app's `public/` folder. At runtime, the server function will forward any requests made to these files and directories to S3. And S3 will serve them directly. [See why.](#workaround-public-static-files-served-out-by-server-function-aws-specific)
146
+
143
147
**Monorepo**
144
148
145
149
In the case of a monorepo, the build output looks slightly different. For example, if the app is located in `packages/web`, the build output looks like this:
146
150
147
151
```
148
152
packages/
149
153
web/
150
-
.next/ -> NextServer
151
-
node_modules/ -> dependencies from root node_modules (optional)
152
-
node_modules/ -> dependencies from package node_modules
154
+
.next/ -> NextServer
155
+
node_modules/ -> dependencies from root node_modules (optional)
156
+
node_modules/ -> dependencies from package node_modules
153
157
```
154
158
155
159
In this case, the server function adapter needs to be created inside `packages/web` next to `.next/`. This is to ensure that the adapter can import dependencies from both `node_modules` folders. It is not a good practice to have the Lambda configuration coupled with the project structure, so instead of setting the Lambda handler to `packages/web/index.mjs`, we will add a wrapper `index.mjs` at the `server-function` bundle root that re-exports the adapter. The resulting structure looks like this:
156
160
157
161
```diff
158
162
packages/
159
163
web/
160
-
.next/ -> NextServer
161
-
node_modules/ -> dependencies from root node_modules (optional)
162
-
+ index.mjs -> server function adapter
163
-
node_modules/ -> dependencies from package node_modules
164
-
+ index.mjs -> adapter wrapper
164
+
.next/ -> NextServer
165
+
+ .open-next/
166
+
+ public-files.json -> `/public` file listing
167
+
node_modules/ -> dependencies from root node_modules (optional)
168
+
+ index.mjs -> server function adapter
169
+
node_modules/ -> dependencies from package node_modules
170
+
+ index.mjs -> adapter wrapper
165
171
```
166
172
167
173
This ensures that the Lambda handler remains at `index.mjs`.
@@ -170,13 +176,13 @@ This ensures that the Lambda handler remains at `index.mjs`.
170
176
171
177
Create a CloudFront distribution, and dispatch requests to their corresponding handlers (behaviors). The following behaviors are configured:
|`/_next/image`| Image optimization | image optimization function |
183
+
|`/_next/data/*`| data requests | server function |
184
+
|`/api/*`| API | server function |
185
+
|`/*`| catch all | server functionfallback to<br />S3 bucket on 503<br />[see why](#workaround-public-static-files-served-out-by-server-function-aws-specific)|
This requires the CloudFront distribution to have the behavior `/favicon.ico` and set the S3 bucket as the origin. However, CloudFront has a [default limit of 25 behaviors per distribution](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/cloudfront-limits.html#limits-web-distributions), so it is not a scalable solution to create one behavior per file.
206
212
207
-
To work around the issue, requests for `public/` files are handled by the catch all behavior `/*`. The behavior sends the request to the server function first, and if the server fails to handle the request, it will fall back to the S3 bucket.
213
+
To work around the issue, requests for `public/` files are handled by the catch all behavior `/*`. This behavior sends the request to the server function first, and if the server fails to handle the request, it will fall back to the S3 bucket.
214
+
215
+
During the build process, the top-level file and directory names in the `public/` folder are saved to the `.open-next/public-files.json` file within the server function bundle. At runtime, the server function checks the request URL path against the file. If the request is made to a file in the `public/` folder:
216
+
217
+
- When deployed to a single region (Lambda), the server function returns a 503 response right away, and S3, which is configured as the failover origin on 503 status code, will serve the file. [Refer to the CloudFront setup.](#cloudfront-distribution)
218
+
- When deployed to the edge (Lambda@Edge), the server function returns the request object. And the request will be handled by S3, which is configured as the origin. [Refer to the CloudFront setup.](#running-at-edge)
208
219
209
-
This means that on cache miss, the request will take slightly longer to process.
220
+
This means that on cache miss, the request may take slightly longer to process.
210
221
211
222
#### WORKAROUND: `NextServer` does not set cache response headers for HTML pages
0 commit comments