Skip to content

Commit dd94426

Browse files
authored
Merge branch 'canary' into cms-builder-io-example
2 parents a532d38 + 34dcede commit dd94426

File tree

442 files changed

+7265
-3378
lines changed

Some content is hidden

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

442 files changed

+7265
-3378
lines changed

.github/workflows/build_test_deploy.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,7 @@ jobs:
432432
BROWSERSTACK: true
433433
BROWSER_NAME: 'safari'
434434
NEXT_TELEMETRY_DISABLED: 1
435+
NEXT_TEST_MODE: 'start'
435436
SKIP_LOCAL_SELENIUM_SERVER: true
436437
BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }}
437438
BROWSERSTACK_ACCESS_KEY: ${{ secrets.BROWSERSTACK_ACCESS_KEY }}
@@ -464,7 +465,7 @@ jobs:
464465
- run: '[[ -z "$BROWSERSTACK_ACCESS_KEY" ]] && echo "Skipping for PR" || npm i -g [email protected]'
465466
if: ${{needs.build.outputs.docsChange != 'docs only change'}}
466467

467-
- run: '[[ -z "$BROWSERSTACK_ACCESS_KEY" ]] && echo "Skipping for PR" || node run-tests.js -c 1 test/integration/production/test/index.test.js'
468+
- run: '[[ -z "$BROWSERSTACK_ACCESS_KEY" ]] && echo "Skipping for PR" || node run-tests.js -c 1 test/integration/production/test/index.test.js test/e2e/basepath.test.ts'
468469
if: ${{needs.build.outputs.docsChange != 'docs only change'}}
469470

470471
testSafariOld:

docs/advanced-features/output-file-tracing.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ module.exports = {
3434

3535
This will create a folder at `.next/standalone` which can then be deployed on it's own without installing `node_modules`.
3636

37-
Additionally, a minimal `server.js` file is also output which can be used instead of `next start`. This minimal server does not handle serving the `static` directory as this should be handled by a CDN instead.
37+
Additionally, a minimal `server.js` file is also output which can be used instead of `next start`. This minimal server does not copy the `.next/static` directory by default as this should ideally be handled by a CDN instead, although it can be copied to the `standalone` folder manually and the `server.js` file will serve it automatically.
3838

3939
## Caveats
4040

docs/api-reference/edge-runtime.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,6 @@ The following JavaScript language features are disabled, and **will not work:**
8282
- [`eval`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval): Evaluates JavaScript code represented as a string
8383
- [`new Function(evalString)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function): Creates a new function with the code provided as an argument
8484

85-
The following Web APIs are currently not supported, but will be in the future:
86-
87-
- [`AbortController`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController): Abort one or more Web requests when desired
88-
8985
## Related
9086

9187
<div class="card">

docs/api-reference/next/server.md

Lines changed: 74 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,13 +70,68 @@ import type { NextFetchEvent } from 'next/server'
7070

7171
## NextResponse
7272

73-
The `NextResponse` object is an extension of the native [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response) interface, with the following added methods and properties:
73+
The `NextResponse` class extends the native [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response) interface, with the following:
74+
75+
### Public methods
76+
77+
Public methods are available on an instance of the `NextResponse` class. Depending on your use case, you can create an instance and assign to a variable, then access the following public methods:
7478

7579
- `cookies` - An object with the cookies in the `Response`
76-
- `cookie` - Set a cookie in the `Response`
80+
- `cookie()` - Set a cookie in the `Response`
81+
- `clearCookie()` - Accepts a `cookie` and clears it
82+
83+
```ts
84+
import { NextResponse } from 'next/server'
85+
import type { NextRequest } from 'next/server'
86+
87+
export function middleware(request: NextRequest) {
88+
// create an instance of the class to access the public methods. This uses `next()`,
89+
// you could use `redirect()` or `rewrite()` as well
90+
let response = NextResponse.next()
91+
// get the cookies from the request
92+
let cookieFromRequest = request.cookies['my-cookie']
93+
// set the `cookie`
94+
response.cookie('hello', 'world')
95+
// set the `cookie` with options
96+
const cookieWithOptions = response.cookie('hello', 'world', {
97+
path: '/',
98+
maxAge: 1000 * 60 * 60 * 24 * 7,
99+
httpOnly: true,
100+
sameSite: 'strict',
101+
domain: 'example.com',
102+
})
103+
// clear the `cookie`
104+
response.clearCookie('hello')
105+
106+
return response
107+
}
108+
```
109+
110+
### Static methods
111+
112+
The following static methods are available on the `NextResponse` class directly:
113+
77114
- `redirect()` - Returns a `NextResponse` with a redirect set
78115
- `rewrite()` - Returns a `NextResponse` with a rewrite set
79116
- `next()` - Returns a `NextResponse` that will continue the middleware chain
117+
- `json()` - A convenience method to create a response that encodes the provided JSON data
118+
119+
```ts
120+
import { NextResponse } from 'next/server'
121+
import type { NextRequest } from 'next/server'
122+
123+
export function middleware(req: NextRequest) {
124+
// if the request is coming from New York, redirect to the home page
125+
if (req.geo.city === 'New York') {
126+
return NextResponse.redirect('/home')
127+
// if the request is coming from London, rewrite to a special page
128+
} else if (req.geo.city === 'London') {
129+
return NextResponse.rewrite('/not-home')
130+
}
131+
132+
return NextResponse.json({ message: 'Hello World!' })
133+
}
134+
```
80135

81136
All methods above return a `NextResponse` object that only takes effect if it's returned in the middleware function.
82137

@@ -86,6 +141,23 @@ All methods above return a `NextResponse` object that only takes effect if it's
86141
import { NextResponse } from 'next/server'
87142
```
88143

144+
### Setting the cookie before a redirect
145+
146+
In order to set the `cookie` _before_ a redirect, you can create an instance of `NextResponse`, then access the `cookie` method on the instance, before returning the response.
147+
148+
Note that there is a [Chrome bug](https://bugs.chromium.org/p/chromium/issues/detail?id=696204) which means the entire redirect chain **must** be from the same origin, if they are from different origins, then the `cookie` might be missing until a refresh.
149+
150+
```ts
151+
import { NextResponse } from 'next/server'
152+
import type { NextRequest } from 'next/server'
153+
154+
export function middleware(req: NextRequest) {
155+
const res = NextResponse.redirect('/') // creates an actual instance
156+
res.cookie('hello', 'world') // can be called on an instance
157+
return res
158+
}
159+
```
160+
89161
### Why does redirect use 307 and 308?
90162

91163
When using `redirect()` you may notice that the status codes used are `307` for a temporary redirect, and `308` for a permanent redirect. While traditionally a `302` was used for a temporary redirect, and a `301` for a permanent redirect, many browsers changed the request method of the redirect, from a `POST` to `GET` request when using a `302`, regardless of the origins request method.

docs/testing.md

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -262,10 +262,10 @@ npx create-next-app@latest --example with-jest with-jest-app
262262

263263
Since the release of [Next.js 12](https://nextjs.org/blog/next-12), Next.js now has built-in configuration for Jest.
264264

265-
To set up Jest, install `jest` , `@testing-library/react`, `@testing-library/jest-dom` and `react-test-renderer`:
265+
To set up Jest, install `jest` , `@testing-library/react`, `@testing-library/jest-dom`:
266266

267267
```bash
268-
npm install --save-dev jest @testing-library/react @testing-library/jest-dom react-test-renderer
268+
npm install --save-dev jest @testing-library/react @testing-library/jest-dom
269269
```
270270

271271
Create a `jest.config.js` file in your project's root directory and add the following:
@@ -284,6 +284,7 @@ const customJestConfig = {
284284
setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
285285
// if using TypeScript with a baseUrl set to the root directory then you need the below for alias' to work
286286
moduleDirectories: ['node_modules', '<rootDir>/'],
287+
testEnvironment: 'jest-environment-jsdom',
287288
}
288289

289290
// createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async
@@ -340,6 +341,7 @@ module.exports = {
340341
'/node_modules/',
341342
'^.+\\.module\\.(css|sass|scss)$',
342343
],
344+
testEnvironment: 'jest-environment-jsdom',
343345
}
344346
```
345347

@@ -430,16 +432,11 @@ Add the Jest executable in watch mode to the `package.json` scripts:
430432

431433
Your project is now ready to run tests. Follow Jests convention by adding tests to the `__tests__` folder in your project's root directory.
432434

433-
For example, we can add a test to check if the `<Index />` component successfully renders a heading:
435+
For example, we can add a test to check if the `<Home />` component successfully renders a heading:
434436

435437
```jsx
436438
// __tests__/index.test.jsx
437439

438-
/**
439-
* @jest-environment jsdom
440-
*/
441-
442-
import React from 'react'
443440
import { render, screen } from '@testing-library/react'
444441
import Home from '../pages/index'
445442

@@ -456,19 +453,17 @@ describe('Home', () => {
456453
})
457454
```
458455

459-
> **Note**: The `@jest-environment jsdom` comment above configures the testing environment as `jsdom` inside the test file because React Testing Library uses DOM elements like `document.body` which will not work in Jest's default `node` testing environment. Alternatively, you can also set the `jsdom` environment globally by adding the Jest configuration option: `"testEnvironment": "jsdom"` in `jest.config.js`.
460-
461-
Optionally, add a [snapshot test](https://jestjs.io/docs/snapshot-testing) to keep track of any unexpected changes to your `<Index />` component:
456+
Optionally, add a [snapshot test](https://jestjs.io/docs/snapshot-testing) to keep track of any unexpected changes to your `<Home />` component:
462457

463458
```jsx
464459
// __tests__/snapshot.js
465-
import React from 'react'
466-
import renderer from 'react-test-renderer'
467-
import Index from '../pages/index'
460+
461+
import { render } from '@testing-library/react'
462+
import Home from '../pages/index'
468463

469464
it('renders homepage unchanged', () => {
470-
const tree = renderer.create(<Index />).toJSON()
471-
expect(tree).toMatchSnapshot()
465+
const { container } = render(<Home />)
466+
expect(container).toMatchSnapshot()
472467
})
473468
```
474469

errors/no-page-custom-font.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
### Why This Error Occurred
44

55
- The custom font you're adding was added to a page - this only adds the font to the specific page and not the entire application.
6-
- The custom font you're adding was added to a separate component within `Document` - this disables automatic font optimiztion.
6+
- The custom font you're adding was added to a separate component within `Document` - this disables automatic font optimization.
77

88
### Possible Ways to Fix It
99

errors/react-hydration-error.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ An example:
1414

1515
```jsx
1616
function MyComponent() {
17-
// This condition depends on `window`. During the first render of the browser the `color` variable will be different
18-
const color = typeof window !== 'undefined' ? 'red' : 'blue
19-
// As color is passed as a prop there is a mismatch between what was rendered server-side vs what was rendered in the first render
20-
return <h1 className={`title ${color}`}>Hello World!</h1>
17+
// This condition depends on `window`. During the first render of the browser the `color` variable will be different
18+
const color = typeof window !== 'undefined' ? 'red' : 'blue'
19+
// As color is passed as a prop there is a mismatch between what was rendered server-side vs what was rendered in the first render
20+
return <h1 className={`title ${color}`}>Hello World!</h1>
2121
}
2222
```
2323

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# The two iron-session values may be left as-is while testing out this example app.
2+
IRON_SESSION_COOKIE_NAME="stytch_next_example_cookie"
3+
IRON_SESSION_PASSWORD="complex_password_at_least_32_characters_long"
4+
# The below values may be found in your Stytch Dashboard: https://stytch.com/dashboard/api-keys
5+
STYTCH_PROJECT_ENV=test
6+
STYTCH_PROJECT_ID="YOUR_STYTCH_PROJECT_ID"
7+
STYTCH_SECRET="YOUR_STYTCH_SECRET"
8+
NEXT_PUBLIC_STYTCH_PUBLIC_TOKEN="YOUR_STYTCH_PUBLIC_TOKEN"
File renamed without changes.
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# Stytch + Next.js example app on Vercel
2+
3+
This is a [Stytch](https://stytch.com) + [Next.js](https://nextjs.org/) project that showcases how to enable elegant authentication in your applicaiton.
4+
5+
<p align="center"><img src="./public/example-app-image.png" alt="stytch" width="50%"/></p>
6+
7+
In this repo, we have two sample auth flows:
8+
9+
- SDK integration: This flow uses Stytch's React component to create a login and sign-up flow using [Email Magic Links](https://stytch.com/docs/api/send-by-email).
10+
- API integration: This flow uses a custom UI with Stytch's backend API for [Onetime Passcodes(OTP) via SMS](https://stytch.com/docs/api/sms-otp-overview) authentication.
11+
12+
Both flows use Stytch's [Node client library](https://github.com/stytchauth/stytch-node) and [`iron-session`](https://github.com/vvo/next-iron-session) for session management.
13+
14+
**Note:** By default this example app enables three of our OAuth providers, Google, Microsoft, and Apple. If you haven't set up these OAuth providers in your [Dashboard](https://stytch.com/dashboard/oauth), you'll receive a redirect error when you attempt to login via those providers. You may remove all OAuth methods by removing `SDKProductTypes.oauth` from the `products` array in [pages/index.tsx](pages/index.tsx) or adjust which ones are displayed by via `oauthOptions.providers` in the same file. More detail on working with OAuth providers in our SDK may be found in our [Docs](https://stytch.com/docs/javascript-sdk#javascript-sdk/oauth).
15+
16+
# Deploy on Vercel
17+
18+
## Setting up Stytch
19+
20+
The first step is to configure the appropriate redirect URLs for your project. You'll set these magic link redirect URLs in the [Redirect URLs](https://stytch.com/dashboard/redirect-urls) section of your Dashboard. Add `https://*.vercel.app:3000` as both a login and sign-up redirect URL.
21+
22+
## Running the example app
23+
24+
Now just click the deploy button below! Once you're signed in to your Vercel account, you'll be guided through how to get up and running quickly. Check out [.env.template](/.env.template) for pointers on filling in the appropriate environment variables for this step.
25+
26+
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fvercel%2Fnext.js%2Fblob%2Fcanary%2Fexamples%2Fauth-with-stytch%2F&env=STYTCH_PROJECT_ENV,STYTCH_PROJECT_ID,STYTCH_SECRET,NEXT_PUBLIC_STYTCH_PUBLIC_TOKEN,IRON_SESSION_PASSWORD,IRON_SESSION_COOKIE_NAME&envDescription=All%20variables%20here%20need%20values%2C%20see%20the%20following%20link%20for%20pointers%20on%20how%20to%20feel%20these%20out.&envLink=https%3A%2F%2Fgithub.com%2Fvercel%2Fnext.js%2Fblob%2Fcanary%2Fexamples%2Fauth-with-stytch%2F.env.template&project-name=stytch-nextjs-vercel&repo-name=stytch-nextjs-vercel&demo-title=Stytch%20on%20Next.js%20with%20Vercel&demo-description=Next.js%20example%20app%20using%20Stytch%20authentication&demo-url=https%3A%2F%2Fgithub.com%2Fvercel%2Fnext.js%2Fblob%2Fcanary%2Fexamples%2Fauth-with-stytch&demo-image=https%3A%2F%2Fstytch.com%2Flogo-preview.png)
27+
28+
# Running locally via `vercel dev`
29+
30+
## Setting up Stytch
31+
32+
After signing up for Stytch, you'll need your Project's `project_id`, `secret`, and `public_token`. You can find these in the [API keys tab](https://stytch.com/dashboard/api-keys).
33+
34+
Once you've gathered these values, add them to a new .env.local file.
35+
Example:
36+
37+
```bash
38+
cp .env.template .env.local
39+
# Replace your keys in new .env.local file
40+
```
41+
42+
Next we'll configure the appropriate redirect URLs for your project, you'll set these magic link URLs for your project in the [Redirect URLs](https://stytch.com/dashboard/redirect-urls) section of your Dashboard. Add `http://localhost:3000/api/authenticate_magic_link` as both a login and sign-up redirect URL.
43+
44+
## Running the example app
45+
46+
Install dependencies by running
47+
48+
```bash
49+
npm install
50+
# or
51+
yarn install
52+
```
53+
54+
You can then run a development server using:
55+
56+
```bash
57+
vercel dev
58+
```
59+
60+
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
61+
62+
## Documentation
63+
64+
Learn more about some of Stytch's products used in this example app:
65+
66+
- [Stytch React](https://www.npmjs.com/package/@stytch/stytch-react)
67+
- [Stytch's node client library](https://www.npmjs.com/package/stytch)
68+
- [iron-session](https://github.com/vvo/next-iron-session)

0 commit comments

Comments
 (0)