Closed eeyang92 closed 5 years ago
Hi @eeyang92 Yes, this code also looks correct to me.
In the tutorial you followed, they create a custom server for handling the requests. Did you also do that? If yes, can you maybe post the code of your custom server? Because next-serverless sets the prefix within the server implementation and then reads it from there in the link. So if the link looks correct, maybe the prefix never gets set in the server. The implementation with a custom server may not be that easy if you have a lot of logic or even other plugins in it.
@cyrilwanner, sorry for the late response, I've been playing around with different configurations, and when I took a look at your source code - it finally became clear what I was doing wrong.
Here is my current setup:
// Copied from https://statsbot.co/blog/a-crash-course-on-serverless-side-rendering-with-reactjs-nextjs-and-aws-lambda/
// server.js
const express = require('express')
const path = require('path')
const dev = process.env.NODE_ENV !== 'production'
const next = require('next')
const pathMatch = require('path-match')
const app = next({ dev })
const handle = app.getRequestHandler()
const { parse } = require('url')
const server = express()
const route = pathMatch()
server.use('/_next', express.static(path.join(__dirname, '.next')))
server.get('/', (req, res) => app.render(req, res, '/'))
server.get('/dogs', (req, res) => app.render(req, res, '/dogs'))
server.get('/dogs/:breed', (req, res) => {
const params = route('/dogs/:breed')(parse(req.url).pathname)
return app.render(req, res, '/dogs/_breed', params)
})
server.get('*', (req, res) => handle(req, res))
module.exports.app = app // Slightly modified here
module.exports.server = server
// index.js
const nextServerless = require('next-serverless/handler')
const { app, server } = require('./server')
module.exports.handler = nextServerless(app, server, () => {
server.listen(3000, () => {
console.log('> Ready on http://localhost:3000')
})
})
With this configuration, all express routing as shown in the example works! Link
is also working as expected.
However, one thing not working is that the local dev environment: next-serverless
does not respect runLocal: () => void
. Looking at the source code, I see:
// from https://github.com/cyrilwanner/next-serverless/blob/master/src/next/server.js
...
module.exports.handler = nextServerless(app, handler, () => {
// create a normal http node server for local usage
createServer(handler).listen(argv.port, argv.hostname, (err) => {
if (err) throw err;
console.log(`> Ready on http://${argv.hostname || 'localhost'}:${argv.port}`);
});
});
Because it is using the http
server rather than my express
server, the custom routing isn't quite working. I believe the fix would be to detect if runLocal
is provided, then use that; otherwise run the default server as you've written above.
Hi @eeyang92
The code which you found with the http server is only the fallback code when no custom server is set up. If a custom server is used (like you do), you will never reach this code but end up here: https://github.com/cyrilwanner/next-serverless/blob/master/src/next/handler.js#L54
The isLambda()
will return false (because it runs locally) and so the runLocal
function will handle everything.
You actually define and start your local server within this param, so from the code I see, your setup looks correct and I can't find something wrong.
So I guess we have to debug it a bit to hopefully find the error.
Did you try to check if the runLocal
function actually gets called (e.g. with a unique console.log or by throwing an error)? If yes and when running locally, which links/routes are working and which are not? Do you get any error or other information in the console?
Ah, I see, indeed your package does export handler
, not server
.
I did get it working - it turns out I had replaced my scripts with next-serverless
instead of running node index.js
on the custom server, so my index.js
script was never being called in the first place. I probably would have realized that earlier if I had changed the console.log
to something else!
Thanks for your help in resolving this issue! I created a repo to demonstrate a working configuration (with typescript): https://github.com/eeyang92/next-serverless-boilerplate
I'm sure it can be refactored, but for now, I'm happy it's working.
I'm glad that it is working now :) Thank you for the boilerplate, this is a perfect way to start a new project!
Hi, I'm follow this tutorial, but have made a few modifications (
next-serverless
being one of them): https://statsbot.co/blog/a-crash-course-on-serverless-side-rendering-with-reactjs-nextjs-and-aws-lambda/I believe I am using the
Link
component correctly, as shown below:However, when I click the links in my
production
lambda, it does not add the prefix and I get a forbidden error message. If I manually type in the URL then it correctly displays the content.