From c5eb5352296239d79dde951a2684ad6dd73d598a Mon Sep 17 00:00:00 2001 From: Luis Alvarez D Date: Wed, 12 Feb 2020 15:19:58 -0500 Subject: [PATCH] [Docs] Apply updates based on feedback (#10352) * Expand on the docs for the serverless target * Added catch all routes to API docs * Added caveat for catch all routes * Added link to Rauch's post about serverless * Add mention of `lang` * Add create-next-app to docs * Updated dynamic import examples to be more descriptive * Even better * Clarify valid catch all routes * Removed unexpected word * Apply suggestions from Joe Co-Authored-By: Joe Haddad * Keep #setup Co-Authored-By: Joe Haddad * Updated docs for the serverless target * Apply suggestions from code review Co-Authored-By: Shu Uesugi * Update docs/getting-started.md Co-Authored-By: Shu Uesugi * Added suggestion from chibicode Co-authored-by: Joe Haddad Co-authored-by: Shu Uesugi --- docs/advanced-features/custom-document.md | 6 +++ docs/advanced-features/dynamic-import.md | 13 +++++- .../next.config.js/build-target.md | 8 ++-- docs/api-reference/next/link.md | 2 +- docs/api-routes/dynamic-api-routes.md | 41 +++++++++++++++++++ docs/getting-started.md | 12 ++++++ docs/routing/dynamic-routes.md | 11 +++-- 7 files changed, 84 insertions(+), 9 deletions(-) diff --git a/docs/advanced-features/custom-document.md b/docs/advanced-features/custom-document.md index 4408cf087f..8af080e719 100644 --- a/docs/advanced-features/custom-document.md +++ b/docs/advanced-features/custom-document.md @@ -37,6 +37,12 @@ export default MyDocument ``, ``, `
` and `` are required for the page to be properly rendered. +Custom attributes are allowed as props, like `lang`: + +```jsx + +``` + The `ctx` object is equivalent to the one received in [`getInitialProps`](/docs/api-reference/data-fetching/getInitialProps.md#context-object), with one addition: - `renderPage`: `Function` - a callback that executes the actual React rendering logic (synchronously). It's useful to decorate this function in order to support server-rendering wrappers like Aphrodite's [`renderStatic`](https://github.com/Khan/aphrodite#server-side-rendering) diff --git a/docs/advanced-features/dynamic-import.md b/docs/advanced-features/dynamic-import.md index adf716f150..547137cbb4 100644 --- a/docs/advanced-features/dynamic-import.md +++ b/docs/advanced-features/dynamic-import.md @@ -17,6 +17,8 @@ You can think of dynamic imports as another way to split your code into manageab ## Basic usage +In the following example, the module `../components/hello` will be dynamically loaded by the page: + ```jsx import dynamic from 'next/dynamic' @@ -35,14 +37,21 @@ function Home() { export default Home ``` +`DynamicComponent` will be the default component returned by `../components/hello`. It works like a regular React Component, and you can pass props to it as you normally would. + ## With named exports +If the dynamic component is not the default export, you can use a named export too. Consider the module `../components/hello.js` which has a named export `Hello`: + ```jsx -// components/hello.js export function Hello() { return

Hello!

} +``` +To dynamically import the `Hello` component, you can return it from the [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) returned by [`import()`](https://github.com/tc39/proposal-dynamic-import#example), like so: + +```jsx import dynamic from 'next/dynamic' const DynamicComponent = dynamic(() => @@ -64,6 +73,8 @@ export default Home ## With custom loading component +An optional `loading` component can be added to render a loading state while the dynamic component is being loaded. For example: + ```jsx import dynamic from 'next/dynamic' diff --git a/docs/api-reference/next.config.js/build-target.md b/docs/api-reference/next.config.js/build-target.md index 7cdec149db..616cad6aca 100644 --- a/docs/api-reference/next.config.js/build-target.md +++ b/docs/api-reference/next.config.js/build-target.md @@ -8,7 +8,7 @@ Next.js supports various build targets, each changing the way your application i ## `server` target -> This is the default target, however, we highly recommend the [`serverless` target](#serverless-target). The `serverless` target enforces additional constraints to keep you in the [Pit of Success](https://blog.codinghorror.com/falling-into-the-pit-of-success/). +> This is the default target, however, we highly recommend the [`serverless` target](#serverless-target). The `serverless` target enforces [additional constraints](https://rauchg.com/2020/2019-in-review#serverless-upgrades-itself) to keep you in the [Pit of Success](https://blog.codinghorror.com/falling-into-the-pit-of-success/). This target is compatible with both `next start` and [custom server](/docs/advanced-features/custom-server.md) setups (it's mandatory for a custom server). @@ -16,9 +16,11 @@ Your application will be built and deployed as a monolith. This is the default t ## `serverless` target -> Deployments to [ZEIT Now](https://zeit.co/home) will automatically enable this target. You do not need to opt-into it yourself, but you can. +> Deployments to [ZEIT Now](https://zeit.co) will automatically enable this target. You do not need to opt-into it yourself, but you can. -This target will output each page in a self-contained Serverless Function. It's only compatible with `next start` or Serverless deployment platforms (like ZEIT Now) — you cannot use the custom server API. +This target will output independent pages that don't require a monolithic server. + +It's only compatible with `next start` or Serverless deployment platforms (like [ZEIT Now](https://zeit.co)) — you cannot use the custom server API. To opt-into this target, set the following configuration in your `next.config.js`: diff --git a/docs/api-reference/next/link.md b/docs/api-reference/next/link.md index 52ed3f450b..832963e961 100644 --- a/docs/api-reference/next/link.md +++ b/docs/api-reference/next/link.md @@ -99,7 +99,7 @@ function NavLink({ href, name }) { export default NavLink ``` -> **Note:** If you’re using [emotion](https://emotion.sh/)’s JSX pragma feature (`@jsx jsx`), you must use `passHref` even if you use an `` tag directly. +> **Note**: If you’re using [emotion](https://emotion.sh/)’s JSX pragma feature (`@jsx jsx`), you must use `passHref` even if you use an `` tag directly. ## If the child is a function component diff --git a/docs/api-routes/dynamic-api-routes.md b/docs/api-routes/dynamic-api-routes.md index 88aa57a7f6..fe700be588 100644 --- a/docs/api-routes/dynamic-api-routes.md +++ b/docs/api-routes/dynamic-api-routes.md @@ -19,3 +19,44 @@ export default (req, res) => { ``` Now, a request to `/api/post/abc` will respond with the text: `Post: abc`. + +### Catch all API routes + +API Routes can be extended to catch all paths by adding three dots (`...`) inside the brackets. For example: + +- `pages/api/post/[...slug].js` matches `/api/post/a`, but also `/api/post/a/b`, `/api/post/a/b/c` and so on. + +> **Note**: You can use names other than `slug`, such as: `[...param]` + +Matched parameters will be sent as a query parameter (`slug` in the example) to the page, and it will always be an array, so, the path `/api/post/a` will have the following `query` object: + +```json +{ "slug": ["a"] } +``` + +And in the case of `/api/post/a/b`, and any other matching path, new parameters will be added to the array, like so: + +```json +{ "slug": ["a", "b"] } +``` + +An API route for `pages/api/post/[...slug].js` could look like this: + +```js +export default (req, res) => { + const { + query: { slug }, + } = req + + res.end(`Post: ${slug.join(', ')}`) +} +``` + +Now, a request to `/api/post/a/b/c` will respond with the text: `Post: a, b, c`. + +## Caveats + +- Predefined API routes take precedence over dynamic API routes, and dynamic API routes over catch all API routes. Take a look at the following examples: + - `pages/api/post/create.js` - Will match `/api/post/create` + - `pages/api/post/[pid].js` - Will match `/api/post/1`, `/api/post/abc`, etc. But not `/api/post/create` + - `pages/api/post/[...slug].js` - Will match `/api/post/1/2`, `/api/post/a/b/c`, etc. But not `/api/post/create`, `/api/post/abc` diff --git a/docs/getting-started.md b/docs/getting-started.md index 64155e0391..640de59dc9 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -17,6 +17,18 @@ The interactive course with quizzes will guide you through everything you need t ## Setup +We recommend creating a new Next.js app using `create-next-app`, which sets up everything automatically for you. To create a project, run: + +```bash +npm init next-app +# or +yarn create next-app +``` + +After the installation is complete, follow the instructions to start the development server. Try editing `pages/index.js` and see the result on your browser. + +## Manual Setup + Install `next`, `react` and `react-dom` in your project: ```bash diff --git a/docs/routing/dynamic-routes.md b/docs/routing/dynamic-routes.md index 0be3069dac..a8c9f9e271 100644 --- a/docs/routing/dynamic-routes.md +++ b/docs/routing/dynamic-routes.md @@ -67,7 +67,9 @@ Client-side navigations to a dynamic route can be handled with [`next/link`](/do Dynamic routes can be extended to catch all paths by adding three dots (`...`) inside the brackets. For example: -- `pages/post/[...slug].js` matches `/post/a`, but also `post/a/b`, `post/a/b/c` and so on. +- `pages/post/[...slug].js` matches `/post/a`, but also `/post/a/b`, `/post/a/b/c` and so on. + +> **Note**: You can use names other than `slug`, such as: `[...param]` Matched parameters will be sent as a query parameter (`slug` in the example) to the page, and it will always be an array, so, the path `/post/a` will have the following `query` object: @@ -75,7 +77,7 @@ Matched parameters will be sent as a query parameter (`slug` in the example) to { "slug": ["a"] } ``` -And in the case of `post/a/b`, and any other matching path, new parameters will be added to the array, like so: +And in the case of `/post/a/b`, and any other matching path, new parameters will be added to the array, like so: ```json { "slug": ["a", "b"] } @@ -85,9 +87,10 @@ And in the case of `post/a/b`, and any other matching path, new parameters will ## Caveats -- Predefined routes take precedence over dynamic routes. Take a look at the following examples: +- Predefined routes take precedence over dynamic routes, and dynamic routes over catch all routes. Take a look at the following examples: - `pages/post/create.js` - Will match `/post/create` - - `pages/post/[pid].js` - Will match `/post/1`, `/post/abc`, etc. but not `/post/create` + - `pages/post/[pid].js` - Will match `/post/1`, `/post/abc`, etc. But not `/post/create` + - `pages/post/[...slug].js` - Will match `/post/1/2`, `/post/a/b/c`, etc. But not `/post/create`, `/post/abc` - Pages that are statically optimized by [Automatic Static Optimization](/docs/advanced-features/automatic-static-optimization.md) will be hydrated without their route parameters provided, i.e `query` will be an empty object (`{}`). After hydration, Next.js will trigger an update to your application to provide the route parameters in the `query` object. -- GitLab