Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add docs for Image Optimization (#18107)
Co-authored-by: Lee Robinson <me@leerob.io> Co-authored-by: Tim Neutkens <timneutkens@me.com>
- Loading branch information
1 parent
301c029
commit 3c6f421
Showing
9 changed files
with
334 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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'` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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)). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
module.exports = { | ||
images: { | ||
domains: ['assets.vercel.com'], | ||
}, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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"> | ||
<Image> | ||
</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 |
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; | ||
} |