Skip to content

Commit

Permalink
Add docs for Image Optimization (#18107)
Browse files Browse the repository at this point in the history
Co-authored-by: Lee Robinson <me@leerob.io>
Co-authored-by: Tim Neutkens <timneutkens@me.com>
  • Loading branch information
3 people committed Oct 24, 2020
1 parent 301c029 commit 3c6f421
Show file tree
Hide file tree
Showing 9 changed files with 334 additions and 0 deletions.
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">
<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;
}

0 comments on commit 3c6f421

Please sign in to comment.