Skip to content

Commit

Permalink
Merge branch 'canary' into rsc-hello-world
Browse files Browse the repository at this point in the history
  • Loading branch information
leerob authored Feb 16, 2022
2 parents a222ff8 + 4f05426 commit c87473c
Show file tree
Hide file tree
Showing 117 changed files with 804 additions and 853 deletions.
2 changes: 1 addition & 1 deletion docs/advanced-features/custom-document.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ Or add a `className` to the `body` tag:

> **Note:** This is advanced and only needed for libraries like CSS-in-JS to support server-side rendering. This is not needed for built-in `styled-jsx` support.
To prepare for [React 18](/docs/advanced-features/react-18.md), we recommend avoiding customizing `getInitiaProps` and `renderPage`, if possible.
To prepare for [React 18](/docs/advanced-features/react-18.md), we recommend avoiding customizing `getInitialProps` and `renderPage`, if possible.

The `ctx` object shown below is equivalent to the one received in [`getInitialProps`](/docs/api-reference/data-fetching/get-initial-props.md#context-object), with the addition of `renderPage`.

Expand Down
19 changes: 18 additions & 1 deletion docs/advanced-features/using-mdx.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,22 @@ The above generates the following `HTML`:
</ul>
```

When you want to style your own elements to give a custom feel to your website or application, you can pass in shortcodes. These are your own custom components that map to `HTML` elements. To do this you use the `MDXProvider` and pass a components object as a prop. Each object key in the components object maps to a `HTML` element name. You also need to specify `providerImportSource: "@mdx-js/react"` in `next.config.js`.
When you want to style your own elements to give a custom feel to your website or application, you can pass in shortcodes. These are your own custom components that map to `HTML` elements. To do this you use the `MDXProvider` and pass a components object as a prop. Each object key in the components object maps to a `HTML` element name.

To enable you need to specify `providerImportSource: "@mdx-js/react"` in `next.config.js`.

```js
// next.config.js

const withMDX = require('@next/mdx')({
// ...
options: {
providerImportSource: '@mdx-js/react',
},
})
```

Then setup the provider in your page

```jsx
// pages/index.js
Expand Down Expand Up @@ -186,6 +201,8 @@ export default function Post(props) {
}
```

If you use it across the site you may want to add the provider to `_app.js` so all MDX pages pick up the custom element config.

## Helpful Links

- [MDX](https://mdxjs.com)
Expand Down
22 changes: 13 additions & 9 deletions docs/api-reference/next/image.md
Original file line number Diff line number Diff line change
Expand Up @@ -252,19 +252,23 @@ const Example = () => (
import Image from 'next/image'
import React from 'react'

const Container = React.forwardRef((props, ref) =>
<div ref={ref} style={{ overflowX: 'scroll', width: '500px' }}>
{props.children}
</div>
const Container = React.forwardRef((props, ref) => {
return (
<div ref={ref} style={{ overflowX: 'scroll', width: '500px' }}>
{props.children}
</div>
)
})

const Example = () => {
const lazyRoot = React.useRef(null)

return (<Container ref={lazyRoot}>
<Image lazyRoot={lazyRoot} src="/one.jpg" width="500" height="500" />
<Image lazyRoot={lazyRoot} src="/two.jpg" width="500" height="500" />
</Container>)
return (
<Container ref={lazyRoot}>
<Image lazyRoot={lazyRoot} src="/one.jpg" width="500" height="500" />
<Image lazyRoot={lazyRoot} src="/two.jpg" width="500" height="500" />
</Container>
)
}
```

Expand Down Expand Up @@ -319,7 +323,7 @@ module.exports = {
The following Image Optimization cloud providers are included:

- Default: Works automatically with `next dev`, `next start`, or a custom server
- [Vercel](https://vercel.com): Works automatically when you deploy on Vercel, no configuration necessary. [Learn more](https://vercel.com/docs/next.js/image-optimization)
- [Vercel](https://vercel.com): Works automatically when you deploy on Vercel, no configuration necessary. [Learn more](https://vercel.com/docs/concepts/image-optimization)
- [Imgix](https://www.imgix.com): `loader: 'imgix'`
- [Cloudinary](https://cloudinary.com): `loader: 'cloudinary'`
- [Akamai](https://www.akamai.com): `loader: 'akamai'`
Expand Down
30 changes: 29 additions & 1 deletion docs/basic-features/data-fetching/get-static-props.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,35 @@ As `getStaticProps` runs only on the server-side, it will never run on the clien

This means that instead of fetching an **API route** from `getStaticProps` (that itself fetches data from an external source), you can write the server-side code directly in `getStaticProps`.

Take the following example. An API route is used to fetch some data from a CMS. That API route is then called directly from `getStaticProps`. This produces an additional call, reducing performance. Instead, the logic for fetching the data from the CMS can be moved to `getStaticProps`.
Take the following example. An API route is used to fetch some data from a CMS. That API route is then called directly from `getStaticProps`. This produces an additional call, reducing performance. Instead, the logic for fetching the data from the CMS can be shared by using a `lib/` directory. Then it can be shared with `getStaticProps`.

```jsx
// lib/fetch-posts.js

// The following function is shared
// with getStaticProps and API routes
// from a `lib/` directory
export async function loadPosts() {
// Call an external API endpoint to get posts
const res = await fetch('https://.../posts/')
const data = await res.json()

return data
}

// pages/blog.js
import { loadPosts } from '../lib/load-posts'

// This function runs only on the server side
export async function getStaticProps() {
// Instead of fetching your `/api` route you can call the same
// function directly in `getStaticProps`
const posts = await loadPosts()

// Props returned will be passed to the page component
return { props: { posts } }
}
```

Alternatively, if you are **not** using API routes to fetch data, then the [`fetch()`](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) API _can_ be used directly in `getStaticProps` to fetch data.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ description: 'Learn how to create or update static pages at runtime with Increme

Next.js allows you to create or update static pages _after_ you’ve built your site. Incremental Static Regeneration (ISR) enables you to use static-generation on a per-page basis, **without needing to rebuild the entire site**. With ISR, you can retain the benefits of static while scaling to millions of pages.

To use ISR add the `revalidate` prop to `getStaticProps`:
To use ISR, add the `revalidate` prop to `getStaticProps`:

```jsx
function Blog({ posts }) {
Expand Down Expand Up @@ -81,8 +81,36 @@ When a request is made to a page that was pre-rendered at build time, it will in
- Any requests to the page after the initial request and before 10 seconds are also cached and instantaneous.
- After the 10-second window, the next request will still show the cached (stale) page
- Next.js triggers a regeneration of the page in the background.
- Once the page has been successfully generated, Next.js will invalidate the cache and show the updated page. If the background regeneration fails, the old page would still be unaltered.
- Once the page generates successfully, Next.js will invalidate the cache and show the updated page. If the background regeneration fails, the old page would still be unaltered.

When a request is made to a path that hasn’t been generated, Next.js will server-render the page on the first request. Future requests will serve the static file from the cache.
When a request is made to a path that hasn’t been generated, Next.js will server-render the page on the first request. Future requests will serve the static file from the cache. ISR on Vercel [persists the cache globally and handles rollbacks](https://vercel.com/docs/concepts/next.js/incremental-static-regeneration).

[Incremental Static Regeneration](https://vercel.com/docs/concepts/next.js/incremental-static-regeneration) covers how to persist the cache globally and handle rollbacks.
## Error Handling and Revalidation

If there is an error inside `getStaticProps` when handling background regeneration, or you manually throw an error, the last successfully generated page will continue to show. On the next subsequent request, Next.js will retry calling `getStaticProps`.

```jsx
export async function getStaticProps() {
// If this request throws an uncaught error, Next.js will
// not invalidate the currently shown page and
// retry getStaticProps on the next request.
const res = await fetch('https://.../posts')
const posts = await res.json()

if (!res.ok) {
// If there is a server error, you might want to
// throw an error instead of returning so that the cache is not updated
// until the next successful request.
throw new Error(`Failed to fetch posts, received status ${res.status}`)
}

// If the request was successful, return the posts
// and revalidate every 10 seconds.
return {
props: {
posts,
},
revalidate: 10,
}
}
```
26 changes: 13 additions & 13 deletions docs/basic-features/environment-variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,26 +152,26 @@ export default async () => {
## Environment Variable Load Order
Depending on the environment (as set by `NODE_ENV`), variables are loaded from the following sources in order from top-to-bottom. In all environments existing env is not overridden by following sources.
Depending on the environment (as set by `NODE_ENV`), Environment Variables are loaded from the following sources in top-to-bottom order. In all environments, the existing `env` is not overridden by following sources:
`NODE_ENV=production`
- `.env.production.local`
- `.env.local`
- `.env.production`
- `.env`
1. `.env.production.local`
1. `.env.local`
1. `.env.production`
1. `.env`
`NODE_ENV=development`
- `.env.development.local`
- `.env.local`
- `.env.development`
- `.env`
1. `.env.development.local`
1. `.env.local`
1. `.env.development`
1. `.env`
`NODE_ENV=test`
- `.env.test.local`
- `.env.test`
- `.env`
1. `.env.test.local`
1. `.env.test`
1. `.env`
_(note: `.env.local` is not loaded when `NODE_ENV=test`)_
> **Note:** `.env.local` is not loaded when `NODE_ENV=test`.
27 changes: 15 additions & 12 deletions docs/guides/building-forms.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ The front-end looks like this:
The HTML `<form>` tag acts as a container for different `<input>` elements like `text` field and submit `button`. Let's study each of these elements:

- `action`: An attribute that specifies where the form data is sent when the form is submitted. It's generally a URL (an absolute URL or a relative URL).
- `method`: Specifies the HTTP method, i.e., `GET` or `POST` used to send data while submitting the form.
- `<label>`: An element that defines the label for other form elements. Label aids accessibility, especially for screen readers.
- `method`: Specifies the [HTTP method](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods), i.e., `GET` or `POST` used to send data while submitting the form.
- `<label>`: An element that defines the label for other form elements. Labels aid accessibility, especially for screen readers.
- `<input>`: The form element that is widely used to structure the form fields. It depends significantly on the value of the `type` attribute. Input types can be `text`, `checkbox`, `email`, `radio`, and more.
- `<button>`: It represents a clickable button that's used to submit the form data.
- `<button>`: Represents a clickable button that's used to submit the form data.

### Form Validation

Expand All @@ -55,11 +55,11 @@ Client-side validation is further categorized as:
### Built-in Form Validation Using `required`, `type`, `minLength`, `maxLength`

- `required`: Specifies which fields must be filled before submitting the form.
- `type`: Tells whether the data should be a number, email id, text string, etc.
- `minLength`: Decides the minimum length for the text data string.
- `maxLength`: Decides the maximum length for the text data string.
- `type`: Specifies the data's type (i.e a number, email address, string, etc).
- `minLength`: Specifies minimum length for the text data string.
- `maxLength`: Specifies maximum length for the text data string.

The following example shows using these attributes:
So, a form using this attributes may look like:

```html
<!-- HTML Form with Built-in Validation -->
Expand All @@ -85,7 +85,7 @@ With these validation checks in place, when a user tries to submit an empty fiel

### JavaScript-based Form Validation

Form Validation is important to ensure that a user has submitted appropriate data. JavaScript offers an additional level of validation along with HTML native form attributes on the client side. Developers generally prefer validating form data through JavaScript because its data processing is faster when compared to server-side validation.
Form Validation is important to ensure that a user has submitted the correct data, in a correct format. JavaScript offers an additional level of validation along with HTML native form attributes on the client side. Developers generally prefer validating form data through JavaScript because its data processing is faster when compared to server-side validation, however front-end validation may be less secure in some scenarios as a malicious user could always send malformed data to your server.

The following example shows using JavaScript to validate a form:

Expand Down Expand Up @@ -143,7 +143,7 @@ The below example shows using the `pattern` attribute on an `input` element:
</form>
```

The password form field must only contain digits (0 to 9) and lowercase alphabets (a to z). No other characters (#,$,&, etc.) are allowed. The rule in RegEx is written as `[a-z]{1,15}`.
The password form field must only contain digits (0 to 9), lowercase alphabets (a to z) and it must be no more than 15 characters in length. No other characters (#,$,&, etc.) are allowed. The rule in RegEx is written as `[a-z0-9]{1,15}`.

![form-validate-regex](https://assets.vercel.com/image/upload/dpr_auto,q_auto,f_auto/nextjs/guides/building-forms/form-validate-regex.jpg)

Expand Down Expand Up @@ -180,13 +180,16 @@ export default function handler(req, res) {
// in the command line where next.js app is running.
console.log('body: ', body)

// Both of these are required.
// Guard clause checks for first and last name,
// and returns early if they are not found
if (!body.first || !body.last) {
return res.json({ data: 'First or last name not found' })
// Sends a HTTP bad request error code
return res.status(400).json({ data: 'First or last name not found' })
}

// Found the name.
res.json({ data: `${body.first} ${body.last}` })
// Sends a HTTP success code
res.status(200).json({ data: `${body.first} ${body.last}` })
}
```

Expand Down
12 changes: 11 additions & 1 deletion docs/middleware.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,16 @@ description: Learn how to use Middleware in Next.js to run code before a request

# Middleware

<details open>
<summary><b>Version History</b></summary>

| Version | Changes |
| --------- | ------------------------------------------------------------------------------------------ |
| `v12.0.9` | Enforce absolute URLs in Edge Runtime ([PR](https://github.com/vercel/next.js/pull/33410)) |
| `v12.0.0` | Middleware (beta) added. |

</details>

Middleware enables you to use code over configuration. This gives you full flexibility in Next.js, because you can run code before a request is completed. Based on the user's incoming request, you can modify the response by rewriting, redirecting, adding headers, or even streaming HTML.

## Usage
Expand Down Expand Up @@ -50,7 +60,7 @@ export type Middleware = (
The function can be a default export and as such, does **not** have to be named `middleware`. Though this is a convention. Also note that you only need to make the function `async` if you are running asynchronous code.
**Note:** Edge Functions are currently in Beta. The API might change as we look to continually make improvements.
[Read the full Middleware API reference.](/docs/api-reference/next/server.md)
## Examples
Expand Down
4 changes: 3 additions & 1 deletion errors/failed-loading-swc.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ SWC requires a binary be downloaded that is compatible specific to your system.

#### Possible Ways to Fix It

You might need to allow optional packages to be installed by your package manager (remove `--no-optional` flag) for the package to download correctly.
When on an M1 Mac and switching from a Node.js version without M1 support e.g. v14 to a version with e.g. v16, you may need a different swc dependency which can require re-installing `node_modules` (`npm i --force` or `yarn install --force`).

Alternatively, you might need to allow optional packages to be installed by your package manager (remove `--no-optional` flag) for the package to download correctly.

If SWC continues to fail to load you can opt-out by disabling `swcMinify` in your `next.config.js` or by adding a `.babelrc` to your project with the following content:

Expand Down
2 changes: 2 additions & 0 deletions errors/page-without-valid-component.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,5 @@ For each, you'll want to check if the file is meant to be a page.
If the file is not meant to be a page, and instead, is a shared component or file, move the file to a different folder like `components` or `lib`.

If the file is meant to be a page, double check you have an `export default` with the React Component instead of an `export`. If you're already using `export default`, make sure the returned value is a valid React Component.

If you need to support a different file extension for a page component (such as `.mdx`) or would like to include non-page files in the `pages` directory, configure [Custom Page Extensions](https://nextjs.org/docs/api-reference/next.config.js/custom-page-extensions) in the `next.config.js`.
2 changes: 1 addition & 1 deletion examples/cms-builder-io/lib/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ export const EXAMPLE_PATH = 'cms-builder-io'
export const CMS_NAME = 'Builder.io'
export const CMS_URL = 'https://builder.io/'
export const HOME_OG_IMAGE_URL =
'https://og-image.now.sh/Next.js%20Blog%20example%20with%20**Builder.io**.png?theme=light&md=1&fontSize=100px&images=https%3A%2F%2Fassets.vercel.com%2Fimage%2Fupload%2Ffront%2Fassets%2Fdesign%2Fnextjs-black-logo.svg&images=https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F79c8b61740bc41d5ae722c000ddb5915'
'https://og-image.vercel.app/Next.js%20Blog%20example%20with%20**Builder.io**.png?theme=light&md=1&fontSize=100px&images=https%3A%2F%2Fassets.vercel.com%2Fimage%2Fupload%2Ffront%2Fassets%2Fdesign%2Fnextjs-black-logo.svg&images=https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F79c8b61740bc41d5ae722c000ddb5915'
export const BUILDER_CONFIG = {
apiKey: process.env.NEXT_PUBLIC_BUILDER_API_KEY,
postsModel: 'post',
Expand Down
6 changes: 3 additions & 3 deletions examples/cms-prepr/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ This example showcases Next.js's [Static Generation](https://nextjs.org/docs/bas

## Demo

- **Live**: [https://next-blog-prepr.now.sh/](https://next-blog-prepr.now.sh/)
- **Preview Mode**: [https://next-blog-prepr.now.sh/api/preview...](https://next-blog-prepr.now.sh/api/preview?secret=237864ihasdhj283768&slug=discover-enjoy-amsterdam)
- **Live**: [https://next-blog-prepr.vercel.app/](https://next-blog-prepr.vercel.app/)
- **Preview Mode**: [https://next-blog-prepr.vercel.app/api/preview...](https://next-blog-prepr.vercel.app/api/preview?secret=237864ihasdhj283768&slug=discover-enjoy-amsterdam)

### [https://next-blog-prepr.now.sh/](https://next-blog-prepr.now.sh/)
### [https://next-blog-prepr.vercel.app/](https://next-blog-prepr.vercel.app/)

### Related examples

Expand Down
4 changes: 2 additions & 2 deletions examples/cms-umbraco-heartcore/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Once you have access to [the environment variables you'll need](#step-3-set-up-e

## How to use

Execute [`create-next-app`](https://github.com/zeit/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init) or [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) to bootstrap the example:
Execute [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init) or [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) to bootstrap the example:

```bash
npx create-next-app --example cms-umbraco-heartcore cms-umbraco-heartcore-app
Expand Down Expand Up @@ -91,7 +91,7 @@ yarn install
yarn dev
```

Your blog should be up and running on [http://localhost:3000](http://localhost:3000)! If it doesn't work, post on [GitHub discussions](https://github.com/zeit/next.js/discussions).
Your blog should be up and running on [http://localhost:3000](http://localhost:3000)! If it doesn't work, post on [GitHub discussions](https://github.com/vercel/next.js/discussions).

### Step 5. Try preview mode

Expand Down
Loading

0 comments on commit c87473c

Please sign in to comment.