I cannot load the assets with a lambda with serverless framework.
Steps to reproduce the behavior, please provide code snippets or a repository:
In lambda function, i'm doing :
app.use("/_next/static", express.static("../static"));
app.use("/static", express.static("../static"));
This doesn't sound like a bug in Next.js 馃
I honestly have no idea. This example is pretty simple.
@vadorequest @Enalmada, do you know what's happenig ?
Idea :
Should we use aws-serverless-express or serverless-express instead of serverless-http ?
I am not doing any lambda right now because my bundle is just so dang huge but just to rule things out and help brainstorm ways of narrow it down...
Can you confirm if this happens on Next 7 or when doing a build from linux (Windows Subsystem for Linux to rule out paths issue)? Can you post the actual error on the chrome console...I am curious if there is any chance it provides any hints.
I'm not using Next 7 for lambda (and you should switch on Next 8, its so much easier for lambda).
I will try on WSL. Will give any hints later, weekend is coming ;)
@timneutkens I don't think that's a Next.js bug either. Assets (especially binary files) need to be treated particularly to work on AWS Lambda. It's more a usage issue IMHO.
I haven't had time to look into how Next 8 deals with assets and what's the recommended way to load them (assuming S3). I'll try to dive in later. Meanwhile, if anybody has any hint regarding the issue, it'd help! :)
Static assets should not be part of the lambdas basically. So indeed use s3 or another static file host.
I'm talking about the static folder generated by next.
All my images, gif, ... is on S3 but I dont want a different process for static js files generated by next.
I'm currently using serverless framework with razzle and basic assets handle is fine : https://github.com/CuistotduCoin/cuistot/tree/master/frontend
I dont see the difference with serverless and/or next on this one (except aws-serverless-express)
JFYI, I tried this :
const compression = require("compression");
const express = require("express");
const { parse } = require("url");
const pathMatch = require("path-match");
const awsServerlessExpress = require('aws-serverless-express');
const isProduction = process.env.NODE_ENV === "production";
// setup Express and hook up Next.js handler
const app = express();
app.use(compression());
const route = pathMatch();
const matches = [];
const binaryMimeTypes = ['*/*'];
// host the static files
app.use("/_next/static", express.static("./static"));
app.use("/static", express.static("./static"));
app.get('/', require('./serverless/pages/index').render)
app.get('*', (req, res) => {
const parsedUrl = parse(req.url, true);
const { pathname, query } = parsedUrl;
let hasMatch = false;
for (const match of matches) {
const params = match.route(pathname);
if (params) {
try {
require(`./serverless/pages${pathname}`).render(req, res, match.page, Object.assign(params, query))
} catch (err) {
require('./serverless/pages/_error').render(req, res, match.page, Object.assign(params, query))
}
hasMatch = true;
break;
}
}
if (!hasMatch) {
try {
require(`./serverless/pages${pathname}`).render(req, res, parsedUrl)
} catch (err) {
require('./serverless/pages/_error').render(req, res, parsedUrl)
}
}
})
// 404 handler
app.get("*", require('./serverless/pages/_error').render);
const server = awsServerlessExpress.createServer(app, null, binaryMimeTypes);
const lambda = (event, context) => awsServerlessExpress.proxy(server, event, context);
// export the wrapped handler for the Lambda runtime
exports.handler = lambda;
not working either
Ok, I resolved this by :
// host the static files
app.use("/_next/static", express.static(path.join(__dirname, "/static")));
I suspect Windows for this. This should do the trick for win and linux.
Can someone with linux try this ?
https://github.com/romainquellec/boilerplate
I can make an example out of this for this repo.
Adding this as great examples : https://github.com/justinwhall/nextjs-serverless-aws
I am experiencing the same issue.
Changing app.use("/_next/static", express.static(path.join(__dirname, "/static"))); to app.use("/_next", express.static(path.join(__dirname, ".next"))); fixed it.
I'm closing this. Will try to make an example out of it later.
in next.config.js, add:
assetPrefix: './'
then in you next app's root html:
src="/_next/...
will become to :
src="./_next/...
then in your nginx conf:
location ^~/yourpath {
proxy_pass http://localhost:yournextappport/;
}
Most helpful comment
Changing
app.use("/_next/static", express.static(path.join(__dirname, "/static")));toapp.use("/_next", express.static(path.join(__dirname, ".next")));fixed it.