In my NextJS project, I'm using koa
as the web framework in server.js
file, what I want to do is as follows,
server.js
per each request,_app.js
, so that the data could be shared by all pages via props or contexts. My question is how could we pass the data generated in server.js
to _app.js
or pages?
Here are some code examples,
//////////////////////////////////////////////////
// server.js
import Koa from "koa";
import Router from "koa-router";
const verified_names = {};
const handle = app.getRequestHandler(); // NextJS use this to handle each request
app.prepare().then(async () => {
const server = new Koa();
const router = new Router();
...
// in verifyNameFunc, if name is verified, will set verified_names[name] = some_data
router.get("/verify_name", verifyNameFunc);
router.get("(.*)", async (ctx) => {
// custom logic starts here: if name is not verified, redirect to /verify_name
const name = ctx.query.name;
if (verified_names[name] === undefined) {
ctx.redirect(`/verify_name?name=${name}`);
}
// HERE: do some external api calls and generate some data
var custom_data = custom_logic(verified_names[name]);
// I think here starts rendering the pages (i.e. enters the execution of `_app.js` and pages)
// QUESTION: how to pass the above `custom_data` to _app.js or pages?
await handle(ctx.req, ctx.res);
}
});
server.use(router.routes());
server.listen(...);
});
//////////////////////////////////////////////////
// _app.js
class MyApp extends App {
...
}
MyApp.getInitialProps = async ({ ctx }) => {
// Can we get the `custom_data` from server.js here?
...
};
The reason why I want to keep the custom_logic
inside server.js
is that,
name
is not verified, a redirect would happen and verifyNameFunc
will set some data into verified_names
. I'm not sure if this redirect could be moved into _app.js
as well?
It's just one of solutions: Create a separate js file (module), where you will export two functions setData()
and getData()
like this:
//////////////////////////////////////////////////
// ./lib/data-manager.js
let promiseResolver = undefined;
const promise = new Promise((resolve) => {
promiseResolver = resolve;
})
export function setData(data) { promiseResolver(data); }
export function async getData() { return promise; }
//////////////////////////////////////////////////
// server.js
import { setData } from "../lib/data-manager"
import Koa from "koa";
import Router from "koa-router";
const verified_names = {};
const handle = app.getRequestHandler(); // NextJS use this to handle each request
app.prepare().then(async () => {
const server = new Koa();
const router = new Router();
...
// in verifyNameFunc, if name is verified, will set verified_names[name] = some_data
router.get("/verify_name", verifyNameFunc);
router.get("(.*)", async (ctx) => {
// custom logic starts here: if name is not verified, redirect to /verify_name
const name = ctx.query.name;
if (verified_names[name] === undefined) {
ctx.redirect(`/verify_name?name=${name}`);
}
// HERE: do some external api calls and generate some data
var custom_data = custom_logic(verified_names[name]);
setData(custom_data); // <-- saving data
// I think here starts rendering the pages (i.e. enters the execution of `_app.js` and pages)
// QUESTION: how to pass the above `custom_data` to _app.js or pages?
await handle(ctx.req, ctx.res);
}
});
server.use(router.routes());
server.listen(...);
});
//////////////////////////////////////////////////
// _app.js
import { getData } from "../lib/data-manager"
class MyApp extends App {
...
}
MyApp.getInitialProps = async ({ ctx }) => {
const custom_data = await getData(); // <-- getting data
};
Keep in mind that getInitialProps
enables server-side rendering in a page and allows you to do initial data population, it means sending the page with the data already populated from the server (See https://nextjs.org/docs/api-reference/data-fetching/getInitialProps ). But, as it was recommended to you, maybe you don't need custom server at all
You can use getInitialProps
and do the redirect in __app.tsx
if you need to.
https://nextjs.org/docs/api-reference/data-fetching/getInitialProps
Also it's rather easy to check if a name is verified in __app.tsx
and then to render a different child based on that. I don't think you need an entire custom server for that.
Also take a look at https://nextjs.org/blog/next-10-2#routing-based-on-headers-and-query-string-parameters .
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.