Skip to content

Commit 6549e05

Browse files
committed
Merge branch 'main' into mk/edge-image-logic
2 parents 0bb9bf8 + bec881b commit 6549e05

Some content is hidden

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

62 files changed

+16481
-21497
lines changed

.release-please-manifest.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
{
2-
"packages/runtime": "4.23.1",
3-
"packages/next": "1.3.0"
2+
"packages/runtime": "4.23.3",
3+
"packages/next": "1.3.1"
44
}

README.md

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ commands separately will not work, because the Next.js Runtime will not generate
1616
If you use [`next/image`](https://nextjs.org/docs/basic-features/image-optimization), your images will be automatically
1717
optimized at runtime, ensuring that they are served at the best size and format. The image will be processed on the
1818
first request which means it may take longer to load, but the generated image is then cached at the edge and served as a
19-
static file to future visitors. By default, Next will deliver WebP images if the browser supports it. WebP is a new
19+
static file to future visitors. By default, Next.js will deliver WebP images if the browser supports it. WebP is a new
2020
image format with wide browser support that will usually generate smaller files than png or jpg. You can additionally
2121
enable the AVIF format, which is often even smaller in filesize than WebP. The drawback is that with particularly large
2222
images AVIF may take too long to generate, meaning the function times-out. You can configure
@@ -48,6 +48,14 @@ Next.js Middleware works out of the box on Netlify. By default, middleware runs
4848
support for running Middleware at the origin, set the environment variable `NEXT_DISABLE_NETLIFY_EDGE` to `true`. Be
4949
aware that this will result in slower performance, as all pages that match middleware must use SSR.
5050

51+
For more details on Next.js Middleware with Netlify, see the [middleware docs](https://github.com/netlify/next-runtime/blob/main/docs/middleware.md).
52+
53+
### Limitations
54+
55+
Due to how the site configuration is handled when it's run using Netlify Edge Functions, data such as `locale` and `defaultLocale` will be missing on the `req.nextUrl` object when running `netlify dev`.
56+
57+
However, this data is available on `req.nextUrl` in a production environment.
58+
5159
## Monorepos
5260

5361
If you are using a monorepo you will need to change `publish` to point to the full path to the built `.next` directory,
@@ -60,6 +68,8 @@ If you are using Nx, then you will need to point `publish` to the folder inside
6068
The Next.js Runtime fully supports ISR on Netlify. For more details see
6169
[the ISR docs](https://github.com/netlify/next-runtime/blob/main/docs/isr.md).
6270

71+
Note that Netlify has a minimum TTL of 60 seconds for revalidation.
72+
6373
## Use with `next export`
6474

6575
If you are using `next export` to generate a static site, you do not need most of the functionality of this Next.js
@@ -111,7 +121,7 @@ If you previously set these values, they're no longer needed and should be remov
111121
- `external_node_modules` in `netlify.toml`
112122
- The environment variable `NEXT_USE_NETLIFY_EDGE` can be removed as this is now the default
113123

114-
The `serverless` and `experimental-serverless-trace` targets are deprecated in Next 12, and all builds with this Next
124+
The `serverless` and `experimental-serverless-trace` targets are deprecated in Next.js 12, and all builds with this Next.js
115125
Runtime will now use the default `server` target. If you previously set the target in your `next.config.js`, you should
116126
remove it.
117127

Lines changed: 72 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,127 +1,149 @@
1+
/* eslint-disable max-lines-per-function */
12
describe('Static Routing', () => {
23
it('renders correct page via SSR on a static route', () => {
3-
cy.request('/getServerSideProps/static/').then((res) => {
4+
cy.request({ url: '/getServerSideProps/static/', headers: { 'x-nf-debug-logging': '1' } }).then((res) => {
45
expect(res.status).to.eq(200)
5-
expect(res.headers).to.have.property('x-render-mode', 'ssr')
6+
expect(res.headers).to.have.property('x-nf-render-mode', 'ssr')
67
expect(res.body).to.contain('Sleepy Hollow')
78
})
89
})
910
it('serves correct static file on a static route', () => {
10-
cy.request('/getStaticProps/static/').then((res) => {
11+
cy.request({ url: '/getStaticProps/static/', headers: { 'x-nf-debug-logging': '1' } }).then((res) => {
1112
expect(res.status).to.eq(200)
12-
expect(res.headers).to.not.have.property('x-render-mode')
13+
expect(res.headers).to.not.have.property('x-nf-render-mode')
1314
expect(res.body).to.contain('Dancing with the Stars')
1415
})
1516
})
1617
it('renders correct page via ODB on a static route', () => {
17-
cy.request('/getStaticProps/with-revalidate/').then((res) => {
18+
cy.request({ url: '/getStaticProps/with-revalidate/', headers: { 'x-nf-debug-logging': '1' } }).then((res) => {
1819
expect(res.status).to.eq(200)
19-
expect(res.headers).to.have.property('x-render-mode', 'isr')
20+
expect(res.headers).to.have.property('x-nf-render-mode', 'odb ttl=1')
2021
expect(res.body).to.contain('Dancing with the Stars')
2122
})
2223
})
2324
})
2425

2526
describe('Dynamic Routing', () => {
2627
it('renders correct page via SSR on a dynamic route', () => {
27-
cy.request('/getServerSideProps/1/').then((res) => {
28+
cy.request({ url: '/getServerSideProps/1/', headers: { 'x-nf-debug-logging': '1' } }).then((res) => {
2829
expect(res.status).to.eq(200)
29-
expect(res.headers).to.have.property('x-render-mode', 'ssr')
30+
expect(res.headers).to.have.property('x-nf-render-mode', 'ssr')
3031
expect(res.body).to.contain('Under the Dome')
3132
})
3233
})
3334
it('renders correct page via SSR on a dynamic catch-all route', () => {
34-
cy.request('/getServerSideProps/all/1/').then((res) => {
35+
cy.request({ url: '/getServerSideProps/all/1/', headers: { 'x-nf-debug-logging': '1' } }).then((res) => {
3536
expect(res.status).to.eq(200)
36-
expect(res.headers).to.have.property('x-render-mode', 'ssr')
37+
expect(res.headers).to.have.property('x-nf-render-mode', 'ssr')
3738
expect(res.body).to.contain('Under the Dome')
3839
})
3940
})
4041
it('serves correct static file on a prerendered dynamic route with fallback: false', () => {
41-
cy.request('/getStaticProps/1/').then((res) => {
42+
cy.request({ url: '/getStaticProps/1/', headers: { 'x-nf-debug-logging': '1' } }).then((res) => {
4243
expect(res.status).to.eq(200)
43-
expect(res.headers).to.not.have.property('x-render-mode')
44+
expect(res.headers).to.not.have.property('x-nf-render-mode')
4445
expect(res.body).to.contain('Under the Dome')
4546
})
4647
})
4748
it('renders custom 404 on a non-prerendered dynamic route with fallback: false', () => {
48-
cy.request({ url: '/getStaticProps/3/', failOnStatusCode: false }).then((res) => {
49-
expect(res.status).to.eq(404)
50-
expect(res.headers).to.have.property('x-render-mode', 'odb')
51-
expect(res.body).to.contain('Custom 404')
52-
})
49+
cy.request({ url: '/getStaticProps/3/', headers: { 'x-nf-debug-logging': '1' }, failOnStatusCode: false }).then(
50+
(res) => {
51+
expect(res.status).to.eq(404)
52+
expect(res.headers).to.have.property('x-nf-render-mode', 'odb')
53+
expect(res.body).to.contain('Custom 404')
54+
},
55+
)
5356
})
5457
it('serves correct static file on a prerendered dynamic route with fallback: true', () => {
55-
cy.request('/getStaticProps/withFallback/1/').then((res) => {
58+
cy.request({ url: '/getStaticProps/withFallback/1/', headers: { 'x-nf-debug-logging': '1' } }).then((res) => {
5659
expect(res.status).to.eq(200)
57-
expect(res.headers).to.not.have.property('x-render-mode')
60+
expect(res.headers).to.not.have.property('x-nf-render-mode')
5861
expect(res.body).to.contain('Under the Dome')
5962
})
6063
})
6164
it('renders fallback page via ODB on a non-prerendered dynamic route with fallback: true', () => {
62-
cy.request('/getStaticProps/withFallback/3/').then((res) => {
65+
cy.request({ url: '/getStaticProps/withFallback/3/', headers: { 'x-nf-debug-logging': '1' } }).then((res) => {
6366
expect(res.status).to.eq(200)
6467
// expect 'odb' until https://github.com/netlify/pillar-runtime/issues/438 is fixed
65-
expect(res.headers).to.have.property('x-render-mode', 'odb')
68+
expect(res.headers).to.have.property('x-nf-render-mode', 'odb')
6669
// expect 'Bitten' until the above is fixed and we can test for fallback 'Loading...' message
6770
expect(res.body).to.contain('Bitten')
6871
})
6972
})
7073
it('serves correct static file on a prerendered dynamic route with fallback: blocking', () => {
71-
cy.request('/getStaticProps/withFallbackBlocking/1/').then((res) => {
72-
expect(res.status).to.eq(200)
73-
expect(res.headers).to.not.have.property('x-render-mode')
74-
expect(res.body).to.contain('Under the Dome')
75-
})
74+
cy.request({ url: '/getStaticProps/withFallbackBlocking/1/', headers: { 'x-nf-debug-logging': '1' } }).then(
75+
(res) => {
76+
expect(res.status).to.eq(200)
77+
expect(res.headers).to.not.have.property('x-nf-render-mode')
78+
expect(res.body).to.contain('Under the Dome')
79+
},
80+
)
7681
})
7782
it('renders correct page via ODB on a non-prerendered dynamic route with fallback: blocking', () => {
78-
cy.request('/getStaticProps/withFallbackBlocking/3/').then((res) => {
79-
expect(res.status).to.eq(200)
80-
expect(res.headers).to.have.property('x-render-mode', 'odb')
81-
expect(res.body).to.contain('Bitten')
82-
})
83+
cy.request({ url: '/getStaticProps/withFallbackBlocking/3/', headers: { 'x-nf-debug-logging': '1' } }).then(
84+
(res) => {
85+
expect(res.status).to.eq(200)
86+
expect(res.headers).to.have.property('x-nf-render-mode', 'odb')
87+
expect(res.body).to.contain('Bitten')
88+
},
89+
)
8390
})
8491
it('renders correct page via ODB on a prerendered dynamic route with revalidate and fallback: false', () => {
85-
cy.request('/getStaticProps/withRevalidate/1/').then((res) => {
92+
cy.request({ url: '/getStaticProps/withRevalidate/1/', headers: { 'x-nf-debug-logging': '1' } }).then((res) => {
8693
expect(res.status).to.eq(200)
87-
expect(res.headers).to.have.property('x-render-mode', 'isr')
94+
expect(res.headers).to.have.property('x-nf-render-mode', 'odb ttl=60')
8895
expect(res.body).to.contain('Under the Dome')
8996
})
9097
})
9198
it('renders custom 404 on a non-prerendered dynamic route with revalidate and fallback: false', () => {
92-
cy.request({ url: '/getStaticProps/withRevalidate/3/', failOnStatusCode: false }).then((res) => {
99+
cy.request({
100+
url: '/getStaticProps/withRevalidate/3/',
101+
headers: { 'x-nf-debug-logging': '1' },
102+
failOnStatusCode: false,
103+
}).then((res) => {
93104
expect(res.status).to.eq(404)
94-
expect(res.headers).to.have.property('x-render-mode', 'odb')
105+
expect(res.headers).to.have.property('x-nf-render-mode', 'odb')
95106
expect(res.body).to.contain('Custom 404')
96107
})
97108
})
98109
it('renders correct page via ODB on a prerendered dynamic route with revalidate and fallback: true', () => {
99-
cy.request('/getStaticProps/withRevalidate/withFallback/1/').then((res) => {
100-
expect(res.status).to.eq(200)
101-
expect(res.headers).to.have.property('x-render-mode', 'isr')
102-
expect(res.body).to.contain('Under the Dome')
103-
})
110+
cy.request({ url: '/getStaticProps/withRevalidate/withFallback/1/', headers: { 'x-nf-debug-logging': '1' } }).then(
111+
(res) => {
112+
expect(res.status).to.eq(200)
113+
expect(res.headers).to.have.property('x-nf-render-mode', 'odb ttl=60')
114+
expect(res.body).to.contain('Under the Dome')
115+
},
116+
)
104117
})
105118
it('renders fallback page via ODB on a non-prerendered dynamic route with revalidate and fallback: true', () => {
106-
cy.request('/getStaticProps/withRevalidate/withFallback/3/').then((res) => {
107-
expect(res.status).to.eq(200)
108-
expect(res.headers).to.have.property('x-render-mode', 'isr')
109-
// expect 'Bitten' until https://github.com/netlify/pillar-runtime/issues/438 is fixed
110-
expect(res.body).to.contain('Bitten')
111-
})
119+
cy.request({ url: '/getStaticProps/withRevalidate/withFallback/3/', headers: { 'x-nf-debug-logging': '1' } }).then(
120+
(res) => {
121+
expect(res.status).to.eq(200)
122+
expect(res.headers).to.have.property('x-nf-render-mode', 'odb ttl=60')
123+
// expect 'Bitten' until https://github.com/netlify/pillar-runtime/issues/438 is fixed
124+
expect(res.body).to.contain('Bitten')
125+
},
126+
)
112127
})
113128
it('renders correct page via ODB on a prerendered dynamic route with revalidate and fallback: blocking', () => {
114-
cy.request('/getStaticProps/withRevalidate/withFallbackBlocking/1/').then((res) => {
129+
cy.request({
130+
url: '/getStaticProps/withRevalidate/withFallbackBlocking/1/',
131+
headers: { 'x-nf-debug-logging': '1' },
132+
}).then((res) => {
115133
expect(res.status).to.eq(200)
116-
expect(res.headers).to.have.property('x-render-mode', 'isr')
134+
expect(res.headers).to.have.property('x-nf-render-mode', 'odb ttl=60')
117135
expect(res.body).to.contain('Under the Dome')
118136
})
119137
})
120138
it('renders correct page via ODB on a non-prerendered dynamic route with revalidate and fallback: blocking', () => {
121-
cy.request('/getStaticProps/withRevalidate/withFallbackBlocking/3/').then((res) => {
139+
cy.request({
140+
url: '/getStaticProps/withRevalidate/withFallbackBlocking/3/',
141+
headers: { 'x-nf-debug-logging': '1' },
142+
}).then((res) => {
122143
expect(res.status).to.eq(200)
123-
expect(res.headers).to.have.property('x-render-mode', 'isr')
144+
expect(res.headers).to.have.property('x-nf-render-mode', 'odb ttl=60')
124145
expect(res.body).to.contain('Bitten')
125146
})
126147
})
127148
})
149+
/* eslint-enable max-lines-per-function */

cypress/integration/nx/general.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ describe('Default site', () => {
44
})
55

66
it('loads home page', () => {
7-
cy.findByRole('heading', { name: 'Welcome to nx-nextjs-monorepo!' })
7+
cy.findByRole('heading', { name: 'Hello there, Welcome demo-monorepo 👋' })
88

99
cy.visit('//')
1010
cy.url().should('eq', `${Cypress.config().baseUrl}/`)

demos/default/next.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ module.exports = {
7878
includePaths: [path.join(__dirname, 'styles-sass-test')],
7979
},
8080
experimental: {
81-
optimizeCss: true,
81+
optimizeCss: false,
8282
images: {
8383
remotePatterns: [
8484
{

demos/default/pages/getStaticProps/with-revalidate.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export async function getStaticProps(context) {
2525
props: {
2626
show: data,
2727
},
28+
// ODB handler will use the minimum TTL=60s
2829
revalidate: 1,
2930
}
3031
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# See http://help.github.com/ignore-files/ for more about ignoring files.
2+
3+
# compiled output
4+
/dist
5+
/tmp
6+
/out-tsc
7+
8+
# dependencies
9+
node_modules
10+
11+
# IDEs and editors
12+
/.idea
13+
.project
14+
.classpath
15+
.c9/
16+
*.launch
17+
.settings/
18+
*.sublime-workspace
19+
20+
# IDE - VSCode
21+
.vscode/*
22+
!.vscode/settings.json
23+
!.vscode/tasks.json
24+
!.vscode/launch.json
25+
!.vscode/extensions.json
26+
27+
# misc
28+
/.sass-cache
29+
/connect.lock
30+
/coverage
31+
/libpeerconnection.log
32+
npm-debug.log
33+
yarn-error.log
34+
testem.log
35+
/typings
36+
37+
# System Files
38+
.DS_Store
39+
Thumbs.db
40+
41+
# Next.js
42+
.next

demos/nx-next-monorepo-demo/.npmrc

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"recommendations": [
3+
"nrwl.angular-console",
4+
"esbenp.prettier-vscode",
5+
"firsttris.vscode-jest-runner",
6+
"dbaeumer.vscode-eslint"
7+
]
8+
}

demos/nx-next-monorepo-demo/README.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
# NxNextjsMonorepo
1+
# NxNextMonorepo
22

3-
This project was generated using [Nx](https://nx.dev). It is a demo site to test that Nx monorepos work properly with the Netlify Next Runtime.
3+
This project was generated using [Nx](https://nx.dev).
44

55
<p style="text-align: center;"><img src="https://raw.githubusercontent.com/nrwl/nx/master/images/nx-logo.png" width="450"></p>
66

7-
🔎 **Smart, Extensible Build Framework**
7+
🔎 **Smart, Fast and Extensible Build System**
88

99
## Adding capabilities to your workspace
1010

@@ -44,7 +44,7 @@ Run `nx g @nrwl/react:lib my-lib` to generate a library.
4444

4545
> You can also use any of the plugins above to generate libraries as well.
4646
47-
Libraries are shareable across libraries and applications. They can be imported from `@nx-nextjs-monorepo/mylib`.
47+
Libraries are shareable across libraries and applications. They can be imported from `@nx-next-monorepo/mylib`.
4848

4949
## Development server
5050

@@ -68,13 +68,13 @@ Run `nx affected:test` to execute the unit tests affected by a change.
6868

6969
## Running end-to-end tests
7070

71-
Run `ng e2e my-app` to execute the end-to-end tests via [Cypress](https://www.cypress.io).
71+
Run `nx e2e my-app` to execute the end-to-end tests via [Cypress](https://www.cypress.io).
7272

7373
Run `nx affected:e2e` to execute the end-to-end tests affected by a change.
7474

7575
## Understand your workspace
7676

77-
Run `nx dep-graph` to see a diagram of the dependencies of your projects.
77+
Run `nx graph` to see a diagram of the dependencies of your projects.
7878

7979
## Further help
8080

demos/nx-next-monorepo-demo/apps/demo-monorepo-e2e/project.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
{
2-
"root": "apps/demo-monorepo-e2e",
2+
"$schema": "../../node_modules/nx/schemas/project-schema.json",
33
"sourceRoot": "apps/demo-monorepo-e2e/src",
44
"projectType": "application",
55
"targets": {
66
"e2e": {
77
"executor": "@nrwl/cypress:cypress",
88
"options": {
99
"cypressConfig": "apps/demo-monorepo-e2e/cypress.json",
10-
"devServerTarget": "demo-monorepo:serve"
10+
"devServerTarget": "demo-monorepo:serve:development",
11+
"testingType": "e2e"
1112
},
1213
"configurations": {
1314
"production": {

demos/nx-next-monorepo-demo/apps/demo-monorepo-e2e/src/integration/app.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@ describe('demo-monorepo', () => {
88
cy.login('my-email@something.com', 'myPassword');
99

1010
// Function helper example, see `../support/app.po.ts` file
11-
getGreeting().contains('Welcome to demo-monorepo!');
11+
getGreeting().contains('Welcome demo-monorepo');
1212
});
1313
});

0 commit comments

Comments
 (0)