Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add docs for Image Optimization #18107

Merged
merged 9 commits into from Oct 24, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
53 changes: 53 additions & 0 deletions docs/api-reference/next/image.md
@@ -0,0 +1,53 @@
---
description: Enable image optimization with the built-in Image component.
---

# next/image

<details>
<summary><b>Examples</b></summary>
<ul>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/image-component">Image Component</a></li>
</ul>
</details>

> Before moving forward, we recommend you to read [Image Optimization](/docs/basic-features/image-optimization.md) first.

Image Optimization can be enabled via the `Image` component exported by `next/image`.

For an example, consider a project with the following files:

- `pages/index.js`
- `public/me.png`

We can serve an optimized image like so:

```jsx
import Image from 'next/image'

function Home() {
return (
<>
<h1>My Homepage</h1>
<Image src="/me.png" alt="me" width={200} height={200} />
<p>Welcome to my homepage!</p>
</>
)
}

export default Home
```

`Image` accepts the following props:

- `src` - The path or URL to the source image. This is required.
- `width` - The intrinsic width of the source image in pixels. Must be an integer without a unit. Required unless `unsized` is true.
- `height` - The intrinsic height of the source image, in pixels. Must be an integer without a unit. Required unless `unsized` is true.
- `sizes` - Defines what proportion of the screen you expect the image to take up. Recommended, as it helps serve the correct sized image to each device. [More info](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#attr-sizes).
- `quality` - The quality of the optimized image, an integer between 1 and 100 where 100 is the best quality. Default 100.
- `loading` - The loading behavior. When `lazy`, defer loading the image until it reaches a calculated distance from the viewport. When `eager`, load the image immediately. Default `lazy`. [More info](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#attr-loading)
- `priority` - When true, the image will be considered high priority and [preload](https://web.dev/preload-responsive-images/).
- `unoptimized` - When true, the source image will be served as-is instead of resizing and changing quality.
- `unsized` - When true, the `width` and `height` requirement can by bypassed. Should _not_ be used with `priority` or above-the-fold images.

Another other properties on the `<Image>` component be passed to the underlying `<img>` element.
113 changes: 113 additions & 0 deletions docs/basic-features/image-optimization.md
@@ -0,0 +1,113 @@
---
description: Next.js supports built-in image optimization, as well as third party loaders for Imgix, Cloudinary, and more! Learn more here.
---

# Image Optimization

<details open>
<summary><b>Examples</b></summary>
<ul>
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/image-component">Image Component</a></li>
</ul>
</details>

Since version **10.0.0** Next.js has a built-in Image Component and Automatic Image Optimization.

The Next.js Image Component (`next/image`) is an extension of the HTML `<img>` element, evolved for the modern web.

The Automatic Image Optimization allows for resizing, optimizing, and serving images in modern formats like [WebP](https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Image_types). This avoids shipping large images to devices with a smaller viewport.

## Image Component

To add an image to your application, import the `next/image` component:

```jsx
import Image from 'next/image'

function Home() {
return (
<>
<h1>My Homepage</h1>
<Image
src="/me.png"
alt="Picture of the author"
width={200}
height={200}
/>
<p>Welcome to my homepage!</p>
</>
)
}

export default Home
```

- `width` and `height` are required to prevent [Cumulative Layout Shift](https://web.dev/cls/), a [Core Web Vital](https://web.dev/vitals/) that Google is going to [use in their search ranking](https://webmasters.googleblog.com/2020/05/evaluating-page-experience.html)
- `width` and `height` are automatically responsive, unlike the HTML `<img>` element

## Configuration

You can configure Image Optimization by using the `images` property in `next.config.js`.

### Sizes

You can specify a list of image widths to allow using the `sizes` property. Since images maintain their aspect ratio using the `width` and `height` attributes of the source image, there is no need to specify height in `next.config.js` – only the width. You can think of these as breakpoints.

```js
module.exports = {
images: {
sizes: [320, 420, 768, 1024, 1200],
},
}
```

### Domains

To enable Image Optimization for images hosted on an external website, use an absolute url for the Image `src` and specify which
`domains` are allowed to be optimized. This is needed to ensure that external urls can't be abused.

```js
module.exports = {
images: {
domains: ['example.com'],
},
}
```

### Loader

If you want to use a cloud image provider to optimize images instead of using the Next.js' built-in image optimization, you can configure the loader and path prefix. This allows you to use relative urls for the Image `src` and automatically generate the correct absolute url for your provider.

```js
module.exports = {
images: {
loader: 'imgix',
path: 'https://example.com/myaccount/',
},
}
```

The following Image Optimization cloud providers are supported:

- Imgix: `loader: 'imgix'`
- Cloudinary: `loader: 'cloudinary'`
- Akamai: `loader: 'akamai'`
- Vercel: No configuration necessary

## Related

For more information on what to do next, we recommend the following sections:

<div class="card">
styfle marked this conversation as resolved.
Show resolved Hide resolved
<a href="/docs/basic-features/built-in-css-support.md">
<b>CSS Support:</b>
<small>Use the built-in CSS support to add custom styles to your app.</small>
</a>
</div>

<div class="card">
- When using `next start` or a custom server image optimization works automatically.
- [Vercel](https://vercel.com): Works automatically when you deploy on Vercel
- [Imgix](https://www.imgix.com): `loader: 'imgix'`
- [Cloudinary](https://cloudinary.com): `loader: 'cloudinary'`
- [Akamai](https://www.akamai.com): `loader: 'akamai'`
34 changes: 34 additions & 0 deletions examples/image-component/.gitignore
@@ -0,0 +1,34 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# local env files
.env.local
.env.development.local
.env.test.local
.env.production.local

# vercel
.vercel
23 changes: 23 additions & 0 deletions examples/image-component/README.md
@@ -0,0 +1,23 @@
# Image Component Example

This example shows how to use the [Image Component in Next.js](https://nextjs.org/docs/api-reference/next/image) serve optimized, responsive images.

The index page ([`pages/index.js`](pages/index.js)) has a couple images, one internal image and one external image. In [`next.config.js`](next.config.js), the `domains` property is used to enable external images. Run or deploy the app to see how it works!

## Deploy your own

Deploy the example using [Vercel](https://vercel.com):

[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/import/project?template=https://github.com/vercel/next.js/tree/canary/examples/image-component)

## How to use

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 image-component image-app
# or
yarn create next-app --example image-component image-app
```

Deploy it to the cloud with [Vercel](https://vercel.com/import?filter=next.js&utm_source=github&utm_medium=readme&utm_campaign=next-example) ([Documentation](https://nextjs.org/docs/deployment)).
5 changes: 5 additions & 0 deletions examples/image-component/next.config.js
@@ -0,0 +1,5 @@
module.exports = {
images: {
domains: ['assets.vercel.com'],
},
}
15 changes: 15 additions & 0 deletions examples/image-component/package.json
@@ -0,0 +1,15 @@
{
"name": "rewrites",
"version": "1.0.0",
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start"
},
"dependencies": {
"next": "latest",
"react": "^16.13.1",
"react-dom": "^16.13.1"
},
"license": "MIT"
}
57 changes: 57 additions & 0 deletions examples/image-component/pages/index.js
@@ -0,0 +1,57 @@
import styles from '../styles.module.css'
import Image from 'next/image'

const Code = (p) => <code className={styles.inlineCode} {...p} />

const Index = () => (
<div className={styles.container}>
<div className={styles.card}>
<h1>Image Component with Next.js</h1>
<p>
The images below use the{' '}
<a href="https://nextjs.org/docs/api-reference/next/image">
&lt;Image&gt;
</a>{' '}
component to ensure optimal format and size for this browser.
</p>
<p>
Images are also lazy loaded by default which means they don't load until
scrolled into view.
</p>
<p>Try scolling down to try it out!</p>
<hr className={styles.hr} />
<p>
The following is an example of a reference to an interal image from the{' '}
<Code>public</Code> directory.
</p>
<p>
Notice that the image is responsive. As you adjust your browser width, a
different sized image is loaded.
</p>
<Image alt="Vercel logo" src="/vercel.png" width={1000} height={1000} />
<hr className={styles.hr} />
<p>
The following is an example of a reference to an external image at{' '}
<Code>assets.vercel.com</Code>.
</p>
<p>
External domains must be configured in <Code>next.config.js</Code> using
the <Code>domains</Code>.
</p>
<Image
alt="Next.js logo"
src="https://assets.vercel.com/image/upload/v1538361091/repositories/next-js/next-js.png"
width={1200}
height={400}
/>
<hr className={styles.hr} />
Checkout the documentation for{' '}
<a href="https://nextjs.org/docs/basic-features/data-fetching">
Image Optimization
</a>{' '}
to learn more.
</div>
</div>
)

export default Index
Binary file added examples/image-component/public/vercel.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
34 changes: 34 additions & 0 deletions examples/image-component/styles.module.css
@@ -0,0 +1,34 @@
.container {
padding: 4rem 1rem;
font-family: -apple-system, BlinkMacSystemFont, sans-serif;
}

.container p {
margin: 1.5rem 0;
}

.card {
max-width: 50rem;
box-shadow: -10px 10px 80px rgba(0, 0, 0, 0.12);
border: 1px solid #eee;
border-radius: 8px;
padding: 2rem;
margin: 0 auto;
}

.inlineCode {
color: #be00ff;
font-size: 16px;
white-space: pre-wrap;
}

.inlineCode::before,
.inlineCode::after {
content: '`';
}

.hr {
border: 0;
border-top: 1px solid #eaeaea;
margin: 1.5rem 0;
}