Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
This repository was archived by the owner on May 10, 2021. It is now read-only.

Commit b4c85b9

Browse files
lindsaylevinejlengstorf
andauthored
initial support for next/image on netlify (#138)
* initial support for next/image on netlify * copy change to next/image caveat in readme Co-authored-by: Jason Lengstorf <jason.lengstorf@netlify.com> Co-authored-by: Jason Lengstorf <jason.lengstorf@netlify.com>
1 parent 853983b commit b4c85b9

14 files changed

+616
-28
lines changed

‎README.md‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ The plugin can be found on [npm here](https://www.npmjs.com/package/@netlify/plu
5050
- [Using Netlify Identity](#using-netlify-identity)
5151
- [Caveats](#caveats)
5252
- [Fallbacks for Pages with `getStaticPaths`](#fallbacks-for-pages-with-getstaticpaths)
53+
- [next/image](#next/image)
5354
- [Credits](#credits)
5455
- [Showcase](#showcase)
5556

@@ -256,6 +257,11 @@ With `next-on-netlify`, when navigating to a path that is not defined in `getSta
256257

257258
For more on this, see: [Issue #7](https://github.com/netlify/next-on-netlify/issues/7#issuecomment-636883539)
258259

260+
### next/image
261+
262+
Our existing solution for next/image is not very performant. We have performance improvements on our roadmap, dependent on internal work.
263+
264+
To get better performance now, we recommend using a cloud provider like Cloudinary ([see the Next.js docs](https://nextjs.org/docs/basic-features/image-optimization#loader)).
259265

260266
## Credits
261267

‎index.js‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ const prepareFolders = require("./lib/steps/prepareFolders");
22
const copyPublicFiles = require("./lib/steps/copyPublicFiles");
33
const copyNextAssets = require("./lib/steps/copyNextAssets");
44
const setupPages = require("./lib/steps/setupPages");
5+
const setupImageFunction = require("./lib/steps/setupImageFunction");
56
const setupRedirects = require("./lib/steps/setupRedirects");
67
const {
78
NETLIFY_PUBLISH_PATH,
@@ -26,6 +27,8 @@ const nextOnNetlify = (options = {}) => {
2627

2728
setupPages({ functionsPath, publishPath });
2829

30+
setupImageFunction(functionsPath);
31+
2932
setupRedirects(publishPath);
3033
};
3134

‎lib/config.js‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ const FUNCTION_TEMPLATE_PATH = join(TEMPLATES_DIR, "netlifyFunction.js");
2828
// This is the file where custom redirects can be configured
2929
const CUSTOM_REDIRECTS_PATH = join(".", "_redirects");
3030

31+
// This is the name used for copying our imageFunction template and for
32+
// creating the next/image redirect
33+
const NEXT_IMAGE_FUNCTION_NAME = "next_image";
34+
3135
module.exports = {
3236
NETLIFY_PUBLISH_PATH,
3337
NETLIFY_FUNCTIONS_PATH,
@@ -37,4 +41,5 @@ module.exports = {
3741
TEMPLATES_DIR,
3842
FUNCTION_TEMPLATE_PATH,
3943
CUSTOM_REDIRECTS_PATH,
44+
NEXT_IMAGE_FUNCTION_NAME,
4045
};

‎lib/steps/setupImageFunction.js‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
const { copySync } = require("fs-extra");
2+
const { join } = require("path");
3+
const { NEXT_IMAGE_FUNCTION_NAME, TEMPLATES_DIR } = require("../config");
4+
5+
// Move our next/image function into the correct functions directory
6+
const setupImageFunction = (functionsPath) => {
7+
const functionName = `${NEXT_IMAGE_FUNCTION_NAME}.js`;
8+
const functionDirectory = join(functionsPath, functionName);
9+
10+
copySync(join(TEMPLATES_DIR, "imageFunction.js"), functionDirectory, {
11+
overwrite: false,
12+
errorOnExist: true,
13+
});
14+
};
15+
16+
module.exports = setupImageFunction;

‎lib/steps/setupRedirects.js‎

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
const { join } = require("path");
22
const { existsSync, readFileSync, writeFileSync } = require("fs-extra");
33
const { logTitle, logItem } = require("../helpers/logger");
4-
const { CUSTOM_REDIRECTS_PATH } = require("../config");
4+
const {
5+
CUSTOM_REDIRECTS_PATH,
6+
NEXT_IMAGE_FUNCTION_NAME,
7+
} = require("../config");
58
const getSortedRoutes = require("../helpers/getSortedRoutes");
69
const getNetlifyRoutes = require("../helpers/getNetlifyRoutes");
710
const isRootCatchAllRedirect = require("../helpers/isRootCatchAllRedirect");
@@ -29,8 +32,14 @@ const setupRedirects = (publishPath) => {
2932
...require("../pages/withoutProps/redirects"),
3033
];
3134

35+
// Add next/image redirect to our image function
36+
nextRedirects.push({
37+
route: "/_next/image* url=:url w=:width q=:quality",
38+
target: `/.netlify/functions/${NEXT_IMAGE_FUNCTION_NAME}?url=:url&w=:width&q=:quality`,
39+
});
40+
3241
// Add _redirect section heading
33-
if(nextRedirects.length>=1)redirects.push("# Next-on-Netlify Redirects");
42+
redirects.push("# Next-on-Netlify Redirects");
3443

3544
// Sort routes: More-specific routes (e.g., static routing) precede
3645
// less-specific routes (e.g., catch-all)

‎lib/templates/imageFunction.js‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
const jimp = require("jimp");
2+
3+
// Function used to mimic next/image and sharp
4+
exports.handler = async (event) => {
5+
const { url, w = 500, q = 75 } = event.queryStringParameters;
6+
const width = parseInt(w);
7+
const quality = parseInt(q);
8+
9+
const imageUrl = url.startsWith("/")
10+
? `${process.env.URL || "http://localhost:8888"}${url}`
11+
: url;
12+
const image = await jimp.read(imageUrl);
13+
14+
image.resize(width, jimp.AUTO).quality(quality);
15+
16+
const imageBuffer = await image.getBufferAsync(image.getMIME());
17+
18+
return {
19+
statusCode: 200,
20+
headers: {
21+
"Content-Type": image.getMIME(),
22+
},
23+
body: imageBuffer.toString("base64"),
24+
isBase64Encoded: true,
25+
};
26+
};

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /