Skip to content

Commit 2ecfcb4

Browse files
authored
Merge pull request #26 from uploadcare/feat/next-13-image
Feat/next 13 image
2 parents b941268 + 5521907 commit 2ecfcb4

21 files changed

+3267
-2744
lines changed

README.md

Lines changed: 69 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ Add your public Uploadcare key to your `.env*` config file. You can copy it from
5656
NEXT_PUBLIC_UPLOADCARE_PUBLIC_KEY="YOUR_PUBLIC_KEY"
5757
```
5858

59-
Alternatively, in case you're using a custom proxy, set the proxy domain.
59+
Alternatively, in case you're using a [custom proxy endpoint][docs-custom-proxy-endpoint], set the proxy domain.
6060

6161
```ini
6262
#.env
@@ -88,7 +88,7 @@ NEXT_PUBLIC_UPLOADCARE_CUSTOM_CDN_DOMAIN="cdn.example.com"
8888
8989
## Usage
9090

91-
**Option 1**. Use the `UploadcareImage` component and leave us the reset ;)
91+
**Option 1**. Use the `UploadcareImage` component and leave us the rest ;)
9292
```tsx
9393
import UploadcareImage from '@uploadcare/nextjs-loader';
9494

@@ -118,7 +118,34 @@ import { uploadcareLoader } from '@uploadcare/nextjs-loader';
118118
/>
119119
```
120120

121-
**Option 3**. Use the [next-image-loader](https://www.npmjs.com/package/next-image-loader) plugin to enable Uploadcare image loader for all images by default
121+
**Option 3 (Next.js v13+ only)**. Use the [`loaderFile` setting][loader-file] to enable Uploadcare image loader for all images by default.
122+
123+
1. Configure the `loaderFile` in your `next.config.js` like the following:
124+
125+
```js
126+
module.exports = {
127+
images: {
128+
loader: 'custom',
129+
loaderFile: './node_modules/@uploadcare/nextjs-loader/build/loader.js',
130+
},
131+
}
132+
```
133+
134+
2. Use `Image` as usual, with Uploadcare loader enabled implicitly:
135+
136+
```tsx
137+
import Image from 'next/image';
138+
139+
<Image
140+
alt="A test image"
141+
src="https://your-domain/image.jpg"
142+
width="400"
143+
height="300"
144+
quality="80"
145+
/>
146+
```
147+
148+
**Option 4**. Use the [next-image-loader](https://www.npmjs.com/package/next-image-loader) plugin to enable Uploadcare image loader for all images by default
122149

123150
In that case, you may not need the `loader: "custom"` setting in your `next.config.js`.
124151

@@ -180,19 +207,45 @@ There are two possible use cases:
180207

181208
#### When `src` is a string
182209

183-
This options is available for the `UploadcareImage` component only. It won't work when you're using custom loader directly.
210+
If you pass `placeholder="blur"` to the `Image` or `UploadcareImage` component, the `blurDataURL` property will be used as the placeholder. In this case you must provide the `blurDataURL` property using our `getBlurDataURL` server-side helper.
184211

185-
If you pass `placeholder="blur"` to the `UploadcareImage` component, it will generate `blurDataURL` with the URL of the placeholder image (not base64) and use it as a placeholder. You can override `blurDataURL`.
212+
Here is the ``getBlurDataURL` interface:
213+
214+
```ts
215+
function getBlurDataURL(
216+
src: string,
217+
width = 10,
218+
quality = 1
219+
): Promise<string>
220+
```
221+
222+
Usage example:
186223

187224
```tsx
188-
<UploadcareImage
189-
alt="A test image"
190-
src="https://your-domain/image.jpg"
191-
width="400"
192-
height="300"
193-
quality="80"
194-
placeholder="blur"
195-
/>
225+
import UploadcareImage, { getBlurDataURL } from '@uploadcare/nextjs-loader';
226+
227+
const BLUR_IMAGE_URL = "https://your-domain/image.jpg"
228+
229+
export const getStaticProps = async () => {
230+
const blurDataURL = await getBlurDataURL(BLUR_IMAGE_URL);
231+
232+
return {
233+
props: { blurDataURL }
234+
};
235+
};
236+
237+
export default ({ blurDataURL }) => {
238+
return (
239+
<UploadcareImage
240+
alt="Blurred image"
241+
src={BLUR_IMAGE_URL}
242+
width="400"
243+
height="300"
244+
placeholder="blur"
245+
blurDataURL={blurDataURL}
246+
/>
247+
)
248+
}
196249
```
197250

198251
#### When `src` is a static import
@@ -246,3 +299,6 @@ Next checks whether the image url which loader generates has the exact value whi
246299
[npm-link]: https://www.npmjs.com/package/@uploadcare/nextjs-loader
247300
[demo-link]: https://uploadcare-nextjs-loader.netlify.app/
248301
[uploadcare-transformation-image-compression-docs]: https://uploadcare.com/docs/transformations/image/compression/?utm_source=github&utm_campaign=nextjs-loader
302+
[docs-custom-proxy-endpoint]: https://uploadcare.com/docs/delivery/proxy/#usage-endpoint
303+
[last-next-12-release]: https://github.com/uploadcare/nextjs-loader/tree/v0.4.0
304+
[loader-file]: https://nextjs.org/docs/api-reference/next/image#loader-configuration

example/next.config.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
module.exports = {
33
reactStrictMode: true,
44
images: {
5-
loader: "custom"
6-
}
5+
loader: 'custom',
6+
loaderFile: "./node_modules/@uploadcare/nextjs-loader/build/loader.js",
7+
},
78
}

example/package.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,16 @@
1111
},
1212
"dependencies": {
1313
"@uploadcare/nextjs-loader": "link:../",
14-
"next": "^12.1.6",
15-
"react": "^18.1.0",
16-
"react-dom": "^18.1.0",
14+
"next": "^13.0.4",
15+
"react": "^18.2.0",
16+
"react-dom": "^18.2.0",
1717
"yarn": "^1.22.18"
1818
},
1919
"devDependencies": {
2020
"@types/node": "^17.0.40",
21-
"@types/react": "^18.0.12",
21+
"@types/react": "^18.0.25",
2222
"eslint": "^8.17.0",
23-
"eslint-config-next": "^12.1.6",
23+
"eslint-config-next": "^13.0.4",
2424
"typescript": "^4.7.3"
2525
}
2626
}

example/pages/index.tsx

Lines changed: 67 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,39 @@
1-
import type { NextPage } from 'next'
2-
import Image from 'next/image'
3-
import UploadcareImage, { uploadcareLoader } from '@uploadcare/nextjs-loader'
4-
import { FC } from 'react'
5-
import styles from '../styles/Home.module.css'
1+
import type { NextPage, GetStaticProps, InferGetStaticPropsType } from 'next';
2+
import Image from 'next/image';
3+
import UploadcareImage, { getBlurDataURL } from '@uploadcare/nextjs-loader';
4+
import { FC } from 'react';
5+
import styles from '../styles/Home.module.css';
6+
import staticImportImage from '../public/static_image.png';
67

78
type CodeProps = {
8-
[key: string]: any
9-
}
10-
const Code: FC<CodeProps> = (p) => <code className={styles.inlineCode} {...p} />
9+
[key: string]: unknown;
10+
};
1111

12-
const Home: NextPage = () => (
12+
const Code: FC<CodeProps> = (p) => (
13+
<code className={styles.inlineCode} {...p} />
14+
);
15+
16+
const BLUR_IMAGE_URL =
17+
'https://ucarecdn.com/c768f1c2-891a-4f54-8e1e-7242df218b51/pinewatt2Hzmz15wGikunsplash.jpg';
18+
19+
export const getStaticProps: GetStaticProps<{
20+
blurDataURL: string;
21+
}> = async () => {
22+
const blurDataURL = await getBlurDataURL(BLUR_IMAGE_URL);
23+
24+
return {
25+
props: { blurDataURL }
26+
};
27+
};
28+
29+
const Home: NextPage<InferGetStaticPropsType<typeof getStaticProps>> = ({
30+
blurDataURL
31+
}) => (
1332
<div className={styles.container}>
1433
<div className={styles.card}>
1534
<h1>
1635
Uploadcare custom loader for Image Component{' '}
17-
<a href="//github.com/uploadcare/nextjs-loader">
36+
<a href="https://github.com/uploadcare/nextjs-loader">
1837
@uploadcare/nextjs-loader
1938
</a>
2039
</h1>
@@ -27,11 +46,12 @@ const Home: NextPage = () => (
2746
proxying through Media Proxy.
2847
</p>
2948
<Image
30-
loader={uploadcareLoader}
3149
alt="Vercel logo"
32-
src="//ucarecdn.com/a6f8abc8-f92e-460a-b7a1-c5cd70a18cdb/vercel.png"
33-
width={1000}
34-
height={1000}
50+
src="https://ucarecdn.com/a6f8abc8-f92e-460a-b7a1-c5cd70a18cdb/vercel.png"
51+
width={500}
52+
height={500}
53+
sizes="(max-width: 50rem) 100vw, 50rem"
54+
className={styles.fullWidthImage}
3555
/>
3656
<hr className={styles.hr} />
3757
<p>
@@ -40,9 +60,11 @@ const Home: NextPage = () => (
4060
</p>
4161
<UploadcareImage
4262
alt="Vercel logo"
43-
src="//ucarecdn.com/a6f8abc8-f92e-460a-b7a1-c5cd70a18cdb/vercel.png"
63+
src="https://ucarecdn.com/a6f8abc8-f92e-460a-b7a1-c5cd70a18cdb/vercel.png"
4464
width={500}
4565
height={500}
66+
sizes="(max-width: 50rem) 100vw, 50rem"
67+
className={styles.fullWidthImage}
4668
/>
4769
<hr className={styles.hr} />
4870
<p>
@@ -53,10 +75,13 @@ const Home: NextPage = () => (
5375
</p>
5476
<UploadcareImage
5577
alt="Vercel logo"
56-
src="//ucarecdn.com/c768f1c2-891a-4f54-8e1e-7242df218b51/pinewatt2Hzmz15wGikunsplash.jpg"
78+
src={BLUR_IMAGE_URL}
5779
width={500}
58-
height={500}
80+
height={333}
5981
placeholder="blur"
82+
blurDataURL={blurDataURL}
83+
sizes="(max-width: 50rem) 100vw, 50rem"
84+
className={styles.fullWidthImage}
6085
/>
6186
<hr className={styles.hr} />
6287
<p>
@@ -66,26 +91,25 @@ const Home: NextPage = () => (
6691
<p>It will be proxied through Media Proxy.</p>
6792
<Image
6893
alt="Next.js logo"
69-
src="//assets.vercel.com/image/upload/v1538361091/repositories/next-js/next-js.png"
70-
width={1200}
71-
height={400}
72-
loader={uploadcareLoader}
94+
src="https://assets.vercel.com/image/upload/v1538361091/repositories/next-js/next-js.png"
95+
width={500}
96+
height={166}
97+
sizes="(max-width: 50rem) 100vw, 50rem"
98+
className={styles.fullWidthImage}
7399
/>
74100
<hr className={styles.hr} />
75101
<p>SVGs and GIFs will be used without transformations</p>
76102
<Image
77103
alt="Next.js logo"
78-
src="//ucarecdn.com/375bba4b-35db-4cb8-8fc7-7540625f2181/next.svg"
104+
src="https://ucarecdn.com/375bba4b-35db-4cb8-8fc7-7540625f2181/next.svg"
79105
width={64}
80106
height={64}
81-
loader={uploadcareLoader}
82107
/>
83108
<Image
84109
alt="Vercel logo"
85-
src="//ucarecdn.com/0f23a269-13eb-4fc9-b378-86f224380d26/vercel.gif"
110+
src="https://ucarecdn.com/0f23a269-13eb-4fc9-b378-86f224380d26/vercel.gif"
86111
width={64}
87112
height={64}
88-
loader={uploadcareLoader}
89113
/>
90114
<hr className={styles.hr} />
91115
<p>
@@ -95,18 +119,30 @@ const Home: NextPage = () => (
95119
<Image
96120
alt="A local image"
97121
src="/local_image.png"
98-
width={494}
99-
height={332}
100-
loader={uploadcareLoader}
122+
width={600}
123+
height={200}
124+
sizes="(max-width: 50rem) 100vw, 50rem"
125+
className={styles.fullWidthImage}
126+
/>
127+
<hr className={styles.hr} />
128+
<p>
129+
Statically imported image will be served AS IS in Development, and
130+
converted to the absolute URL and passed to the proxy in Production
131+
</p>
132+
<Image
133+
alt="A statically imported image"
134+
src={staticImportImage}
135+
sizes="(max-width: 50rem) 100vw, 50rem"
136+
className={styles.fullWidthImage}
101137
/>
102138
<hr className={styles.hr} />
103139
Checkout the project documentation on Github{' '}
104-
<a href="//github.com/uploadcare/nextjs-loader">
140+
<a href="https://github.com/uploadcare/nextjs-loader">
105141
@uploadcare/nextjs-loader
106142
</a>
107143
.
108144
</div>
109145
</div>
110-
)
146+
);
111147

112-
export default Home
148+
export default Home;

example/public/local_image.png

11.1 KB
Loading

example/public/static_image.png

20 KB
Loading

example/styles/Home.module.css

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,8 @@
3232
border-top: 1px solid #eaeaea;
3333
margin: 1.5rem 0;
3434
}
35+
36+
.fullWidthImage {
37+
width: 100%;
38+
height: auto;
39+
}

0 commit comments

Comments
 (0)