I'm trying to statically export a next.js app. The docs says the page object has only 2 values: page
and query
. Is there a way to pass additional props to the page?
I've tried to use query
for this, but it seems that next's router is not aware of the route's query
object. Hence it didn't work.
In other words, I have a list of blog posts at build time, how could I inline them to the page (page component)?
I guess react-static
has a routeInfo.json
which is prefetched for every route. I wonder if there is anything similar to it in next.js.
UPD Apr 4 20 At least in the next.js 9.3 there are getStaticProps
and getStaticPaths
const IndexPage: NextPage<{ names: string[] }> = (props) => {
return (
<main>
<section>
{props.names.map((name) => (
<div key={name}>
<Link href={`/users/${name}`}>
<a>{name}</a>
</Link>
</div>
))}
</section>
</main>
);
};
export const getStaticProps: GetStaticProps = async () => {
const data: User[] = readJsonSync("./data.json");
return {
props: {
names: data.map((user) => user.name),
},
};
};
export default IndexPage;
UPD Dec 4 19
There is an RFC for getStaticProps
which solves this: https://github.com/zeit/next.js/issues/9524
Here is what I ended up with.
_app.js:
import React from "react";
import App, { Container } from "next/app";
import fs from "fs";
import { resolve, join } from "path";
export default class extends App {
static async getInitialProps({ Component, ctx }) {
const { req, asPath } = ctx;
let pageProps = {};
if (Component.getInitialProps) {
pageProps = await Component.getInitialProps(ctx);
}
let p;
if (req) {
p = JSON.parse(
fs.readFileSync(resolve(join("data", asPath, "route.json"))).toString()
);
} else {
p = await (await fetch(`/data${asPath}/route.json`)).json();
}
return { pageProps: { ...pageProps, ...p } };
}
render() {
const { Component, pageProps } = this.props;
return (
<Container>
<Component {...pageProps} />
</Container>
);
}
}
in next.config.js:
const fetch = require("isomorphic-unfetch");
const fs = require("fs");
const path = require("path");
const fse = require("fs-extra");
const withBundleAnalyzer = require("@next/bundle-analyzer")({
enabled: false
});
module.exports = withBundleAnalyzer({
webpack(config) {
config.node = { fs: "empty", path: "empty" };
return config;
},
async exportPathMap() {
const response = await fetch(
"https://jsonplaceholder.typicode.com/posts?_page=1"
);
const postList = await response.json();
fs.writeFileSync(
path.resolve(`data/route.json`),
JSON.stringify({ postList }, null, 2)
);
for (let i = 0; i < postList.length; ++i) {
const id = postList[i].id;
const response = await fetch(
`https://jsonplaceholder.typicode.com/posts/${id}`
);
const post = await response.json();
const fn = path.resolve(`data/post/${id}/route.json`);
await fse.outputFile(fn, JSON.stringify(post, null, 2));
}
const pages = postList.reduce(
(pages, post) =>
Object.assign({}, pages, {
[`/post/${post.id}`]: {
page: "/post"
}
}),
{}
);
return Object.assign({}, pages, {
"/": { page: "/" }
});
}
});
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.