Skip to content

Commit

Permalink
Merge branch 'canary' into invalid-route-objects
Browse files Browse the repository at this point in the history
  • Loading branch information
Luis Alvarez D committed Jan 23, 2020
2 parents 41d0d14 + f4a5b61 commit c47cf0a
Show file tree
Hide file tree
Showing 174 changed files with 2,914 additions and 98 deletions.
134 changes: 134 additions & 0 deletions docs/advanced-features/customizing-postcss-config.md
@@ -0,0 +1,134 @@
---
description: Extend the PostCSS config and plugins added by Next.js with your own.
---

# Customizing PostCSS Config

<details open>
<summary><b>Examples</b></summary>
<ul>
<li><a href="https://github.com/zeit/next.js/tree/canary/examples/with-tailwindcss">Tailwind CSS Example</a></li>
</ul>
</details>

## Default Behavior

Next.js compiles CSS for its [built-in CSS support](/docs/basic-features/built-in-css-support) using PostCSS.

Out of the box, with no configuration, Next.js compiles CSS with the following transformations:

1. [Autoprefixer](https://github.com/postcss/autoprefixer) automatically adds vendor prefixes to CSS rules (back to IE11).
1. [Cross-browser Flexbox bugs](https://github.com/philipwalton/flexbugs) are corrected to behave like [the spec](https://www.w3.org/TR/css-flexbox-1/).
1. New CSS features are automatically compiled for Internet Explorer 11 compatibility:
- [`all` Property](https://developer.mozilla.org/en-US/docs/Web/CSS/all)
- [Break Properties](https://developer.mozilla.org/en-US/docs/Web/CSS/break-after)
- [`font-variant` Property](https://developer.mozilla.org/en-US/docs/Web/CSS/font-variant)
- [Gap Properties](https://developer.mozilla.org/en-US/docs/Web/CSS/gap)
- [Grid Layout](https://developer.mozilla.org/en-US/docs/Web/CSS/grid)
- [Media Query Ranges](https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries/Using_media_queries#Syntax_improvements_in_Level_4)

By default, [Custom Properties](https://developer.mozilla.org/en-US/docs/Web/CSS/var) (CSS variables) are **not compiled** for IE11 support.

CSS variables are not compiled because it is [not possible to safely do so](https://github.com/MadLittleMods/postcss-css-variables#caveats).
If you must use variables, consider using something like [Sass variables](https://sass-lang.com/documentation/variables) which are compiled away by [Sass](https://sass-lang.com/).

## Customizing Target Browsers

Next.js allows you to configure the target browsers (for [Autoprefixer](https://github.com/postcss/autoprefixer) and compiled css features) through [Browserslist](https://github.com/browserslist/browserslist).

To customize browserslist, create a `browserslist` key in your `package.json` like so:

```json
{
"browserslist": [">0.3%", "not ie 11", "not dead", "not op_mini all"]
}
```

You can use the [browserl.ist](https://browserl.ist/?q=%3E0.3%25%2C+not+ie+11%2C+not+dead%2C+not+op_mini+all) tool to visualize what browsers you are targeting.

## CSS Modules

No configuration is needed to support CSS Modules. To enable CSS Modules for a file, rename the file to have the extension `.module.css`.

You can learn more about [Next.js' CSS Module support here](/docs/basic-features/built-in-css-support).

## Customizing Plugins

> **Warning**: When you define a custom PostCSS configuration file, Next.js **completely disables** the defaults listed above.
> Be sure to manually configure all features you need compiled, including [Autoprefixer](https://github.com/postcss/autoprefixer).
To customize the PostCSS configuration, create a `postcss.config.json` file in the root of your project.

This is the default configuration used by Next.js:

```json
{
"plugins": [
"postcss-flexbugs-fixes",
[
"postcss-preset-env",
{
"autoprefixer": {
"flexbox": "no-2009"
},
"stage": 3,
"features": {
"custom-properties": false
}
}
]
]
}
```

> **Note**: Next.js also allows the file to be named `.postcssrc.json`, or, to be read from the `postcss` key in `package.json`.
It is also possible to configure PostCSS with a `postcss.config.js` file, which is useful when you want to conditionally include plugins based on environment:

```js
module.exports = {
plugins:
process.env.NODE_ENV === 'production'
? [
'postcss-flexbugs-fixes',
[
'postcss-preset-env',
{
autoprefixer: {
flexbox: 'no-2009',
},
stage: 3,
features: {
'custom-properties': false,
},
},
],
]
: [
// No transformations in development
],
}
```

Do **not use `require()`** to import the PostCSS Plugins. Plugins must be provided as strings.

> **Note**: Next.js also allows the file to be named `.postcssrc.js`.
> **Note**: If your `postcss.config.js` needs to support other non-Next.js tools in the same project, you must use the interoperable object-based format instead:
>
> ```js
> module.exports = {
> plugins: {
> 'postcss-flexbugs-fixes': {},
> 'postcss-preset-env': {
> autoprefixer: {
> flexbox: 'no-2009',
> },
> stage: 3,
> features: {
> 'custom-properties': false,
> },
> },
> },
> }
> ```
2 changes: 1 addition & 1 deletion docs/api-reference/next.config.js/runtime-configuration.md
Expand Up @@ -28,7 +28,7 @@ Place any server-only runtime config under `serverRuntimeConfig`.

Anything accessible to both client and server-side code should be under `publicRuntimeConfig`.

> A page that relies on `publicRuntimeConfig` **must** use `getInitialProps` to opt-out of [Automatic Static Optimization](/docs/advanced-features/automatic-static-optimization.md).
> A page that relies on `publicRuntimeConfig` **must** use `getInitialProps` to opt-out of [Automatic Static Optimization](/docs/advanced-features/automatic-static-optimization.md). Runtime configuration won't be available to any page (or component in a page) without `getInitialProps`.
To get access to the runtime configs in your app use `next/config`, like so:

Expand Down
59 changes: 32 additions & 27 deletions docs/api-reference/next/link.md
Expand Up @@ -49,6 +49,8 @@ export default Home
- [`replace`](#replace-the-url-instead-of-push) - Replace the current `history` state instead of adding a new url into the stack. Defaults to `false`
- [`scroll`](#disable-scrolling-to-the-top-of-the-page) - Scroll to the top of the page after a navigation. Defaults to `true`

External URLs, and any links that don't require a route navigation using `/pages`, don't need to be handled with `Link`; use the anchor tag for such cases instead.

## Dynamic routes

A `Link` to a dynamic route is a combination of the `href` and `as` props. A link to the page `pages/post/[pid].js` will look like this:
Expand All @@ -72,12 +74,38 @@ const pids = ['id1', 'id2', 'id3']
}
```

## Example with `React.forwardRef`
## If the child is a custom component that wraps an `<a>` tag

If the child of `Link` is a custom component that wraps an `<a>` tag, you must add `passHref` to `Link`. This is necessary if you’re using libraries like [styled-components](https://styled-components.com/). Without this, the `<a>` tag will not have the `href` attribute, which might hurt your site’s SEO.

```jsx
import Link from 'next/link'
import styled from 'styled-components'

// This creates a custom component that wraps an <a> tag
const RedLink = styled.a`
color: red;
`

function NavLink({ href, name }) {
// Must add passHref to Link
return (
<Link href={href} passHref>
<RedLink>{name}</RedLink>
</Link>
)
}

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 `<a>` tag directly.
## If the child is a function component

If the child component in `Link` is a function component, you'll need to wrap it in [`React.forwardRef`](https://reactjs.org/docs/react-api.html#reactforwardref) like in the following example:
If the child of `Link` is a function component, in addition to using `passHref`, you must wrap the component in [`React.forwardRef`](https://reactjs.org/docs/react-api.html#reactforwardref):

```jsx
import React from 'react'
import Link from 'next/link'

// `onClick`, `href`, and `ref` need to be passed to the DOM element
Expand All @@ -92,7 +120,7 @@ const MyButton = React.forwardRef(({ onClick, href }, ref) => {

function Home() {
return (
<Link href="/about">
<Link href="/about" passHref>
<MyButton />
</Link>
)
Expand Down Expand Up @@ -145,29 +173,6 @@ The default behavior of the `Link` component is to `push` a new URL into the `hi

The child of `Link` is `<img>` instead of `<a>`. `Link` will send the `onClick` property to `<img>` but won't pass the `href` property.

## Forcing `Link` to expose `href` to its child

If the child is an `<a>` tag and doesn't have a `href` attribute we specify it so that the repetition is not needed by the user. However, sometimes, you’ll want to pass an `<a>` tag inside of a wrapper and `Link` won’t recognize it as a _hyperlink_, and, consequently, won’t transfer its `href` to the child.

In cases like that, you can add the `passHref` property to `Link`, forcing it to expose its `href` property to the child. Take a look at the following example:

```jsx
import Link from 'next/link'
import Unexpected_A from 'third-library'

function NavLink({ href, name }) {
return (
<Link href={href} passHref>
<Unexpected_A>{name}</Unexpected_A>
</Link>
)
}

export default NavLink
```

> **Please note**: using a tag other than `<a>` and failing to pass `passHref` may result in links that appear to navigate correctly, but, when being crawled by search engines, will not be recognized as links (owing to the lack of `href` attribute). This may result in negative effects on your sites SEO.
## Disable scrolling to the top of the page

The default behavior of `Link` is to scroll to the top of the page. When there is a hash defined it will scroll to the specific id, just like a normal `<a>` tag. To prevent scrolling to the top / hash `scroll={false}` can be added to `Link`:
Expand Down
2 changes: 2 additions & 0 deletions docs/api-routes/introduction.md
Expand Up @@ -46,6 +46,8 @@ export default (req, res) => {
}
```

To fetch API endpoints, take a look into any of the examples at the start of this section.

> API Routes [do not specify CORS headers](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS), meaning they are **same-origin only** by default. You can customize such behavior by wrapping the request handler with [micro-cors](/docs/api-routes/api-middlewares.md#micro-support).
> API Routes do not increase your client-side bundle size. They are server-side only bundles.
Expand Down
18 changes: 15 additions & 3 deletions docs/basic-features/built-in-css-support.md
Expand Up @@ -157,10 +157,22 @@ export default HelloWorld

Please see the [styled-jsx documentation](https://github.com/zeit/styled-jsx) for more examples.

## Sass, Less, and Stylus Support
## Sass Support

To support importing `.scss``.less` or `.styl` files you can use the following plugins:
Next.js allows you to import Sass using both the `.scss` and `.sass` extensions.
You can use component-level Sass via CSS Modules and the `.module.scss` or `.module.sass` extension.

Before you can use Next.js' built-in Sass support, be sure to install [`sass`](https://github.com/sass/sass):

```bash
npm install sass
```

Sass support has the same benefits and restrictions as the built-in CSS support detailed above.

## Less and Stylus Support

To support importing `.less` or `.styl` files you can use the following plugins:

- [@zeit/next-sass](https://github.com/zeit/next-plugins/tree/master/packages/next-sass)
- [@zeit/next-less](https://github.com/zeit/next-plugins/tree/master/packages/next-less)
- [@zeit/next-stylus](https://github.com/zeit/next-plugins/tree/master/packages/next-stylus)
20 changes: 20 additions & 0 deletions errors/no-cache.md
Expand Up @@ -74,3 +74,23 @@ cache:
- 'node_modules/**/*' # Cache `node_modules` for faster `yarn` or `npm i`
- '.next/cache/**/*' # Cache Next.js for faster application rebuilds
```

**Bitbucket Pipelines**

Add or merge the following into your `bitbucket-pipelines.yml` at the top level (same level as `pipelines`):

```yaml
definitions:
caches:
nextcache: .next/cache
```

Then reference it in the `caches` section of your pipeline's `step`:

```yaml
- step:
name: your_step_name
caches:
- node
- nextcache
```
2 changes: 1 addition & 1 deletion examples/form-handler/README.md
@@ -1,6 +1,6 @@
# Form Handler

Sometimes handle multiple forms can be tricky, the idea is to have a global reducer with the name of each form and the inputs of it; making accessible everywhere.
Sometimes handling multiple forms can be tricky. The idea in this example is to have a global reducer with the name of each form and the inputs of it; making accessible everywhere.

## How to use

Expand Down
6 changes: 0 additions & 6 deletions examples/gh-pages/next.config.js
Expand Up @@ -5,11 +5,5 @@
const debug = process.env.NODE_ENV !== 'production'

module.exports = {
exportPathMap: function() {
return {
'/': { page: '/' },
'/about': { page: '/about' },
}
},
assetPrefix: !debug ? '/Next-gh-page-example/' : '',
}
8 changes: 0 additions & 8 deletions examples/with-dynamic-import/next.config.js

This file was deleted.

16 changes: 15 additions & 1 deletion examples/with-graphql-faunadb/README.md
Expand Up @@ -16,7 +16,21 @@ By importing a `.gql` or `.graphql` schema into FaunaDB ([see our sample schema

You can start with this template [using `create-next-app`](#using-create-next-app) or by [downloading the repository manually](#download-manually).

To use a live FaunaDB database, create one and import this example's `schema.gql` file using the FaunaDB console. Create a client secret, then paste it into `next.config.js`.
To use a live FaunaDB database, create a database at [dashboard.fauna.com](https://dashboard.fauna.com/) and generate a server token by going to the **Security** tab on the left and then click **New Key**. Give the new key a name and select the 'Server' Role. Copy the token since the setup script will ask for it. Do not use it in the frontend, it has superpowers which you don't want to give to your users.

The database can then be set up with the delivered setup by running:

```
yarn setup
```

This script will ask for the server token. Once you provide it with a valid token, this is what the script automatically does for you:

- **Import the GraphQL schema**, by importing a GraphQL schema in FaunaDB, FaunaDB automatically sets up collections and indexes to support your queries. This is now done for you with this script but can also be done from the [dashboard.fauna.com](https://dashboard.fauna.com/) UI by going to the GraphQL tab
- **Create a role suitable for the Client**, FaunaDB has a security system that allows you to define which resources can be accessed for a specific token. That's how we limit our clients powers, feel free to look at the scripts/setup.js script to see how we make roles and tokens.
- **Create a token for that role** which is printed, this is the token to be used in the frontend.

At the end, the newly generated client token will be printed and should be used to replace the '< GRAPHQL_SECRET >' placeholder in the next.config.js config.

### Using `create-next-app`

Expand Down
2 changes: 1 addition & 1 deletion examples/with-graphql-faunadb/next.config.js
Expand Up @@ -8,7 +8,7 @@ module.exports = {
| https://docs.fauna.com/fauna/current/security/
|--------------------------------------------------
*/
faunaDbSecret: 'fnADcnWRUcACE_6uDSw05MspruDdWKk88ZSmsm2a',
faunaDbSecret: '< GRAPHQL_SECRET >',
faunaDbGraphQlEndpoint: 'https://graphql.fauna.com/graphql',
},
}
8 changes: 7 additions & 1 deletion examples/with-graphql-faunadb/package.json
Expand Up @@ -5,11 +5,17 @@
"scripts": {
"dev": "next",
"build": "next build",
"start": "next start"
"start": "next start",
"setup": "node ./scripts/setup.js"
},
"dependencies": {
"next": "latest",
"react": "^16.10.2",
"react-dom": "^16.10.2"
},
"devDependencies": {
"faunadb": "2.11.1",
"request": "2.88.0",
"stream-to-promise": "2.2.0"
}
}

0 comments on commit c47cf0a

Please sign in to comment.