我有一个顶级页面,用于 95% 的内容/[...slug].js
我有一个无头 CMS,所以我不需要为路由创建单独的文件夹。
我在 CMS 中的文件夹结构中有内容,例如/holidays/railways
和/holidays/cruising
在前端我可以按原样访问它,一切都很好。
但是,当在这些页面中放置 Next JS Link 和 Router 并单击它们时,URL 最终会更新,但内容将保持不变。
我试过做:
<NextLink href="/[...slug]" as="/holidays/cruising">
Destinations test
</NextLink>
网址现在是/holidays/cruising
,但内容仍然是/holidays/railways
- 以前有人遇到过这个问题吗?
我一直很想holidays
在 Next JS 页面中创建文件夹并放置一个[slug].js
,但如果这不起作用,我不想尝试这个。
这是我的/[...slug].js
页面
import Head from "next/head";
import Storyblok, { useStoryblok } from "lib/storyblok";
import Components from "components";
import ThemeProvider from "ThemeProvider";
const Slug = ({ page, preview }) => {
let story = useStoryblok(page, preview);
return (
<ThemeProvider>
<Head>
<title>Page</title>
</Head>
<Components {...story.content} key={story.content._uid} />
</ThemeProvider>
);
};
export default Slug;
export async function getStaticProps({ params = {}, preview }) {
let slug = params.slug ? params.slug.join("/") : "home";
let sbParams = {
version: "published",
cv: "",
resolve_relations: ""
};
if (preview) {
sbParams.version = "draft";
sbParams.cv = Date.now();
}
const { data } = await Storyblok.get(`cdn/stories/${slug}`, sbParams);
let props = {
page: data.story || {},
preview: preview || false
};
return {
props,
revalidate: 60
};
}
export async function getStaticPaths() {
let { data } = await Storyblok.get("cdn/links/");
let paths = [];
Object.keys(data.links).forEach(link => {
if (data.links[link].is_folder || data.links[link].slug === "home") return;
paths.push({ params: { slug: data.links[link].slug.split("/") } });
});
return {
paths,
fallback: "blocking"
};
}
storyblok.js
import { useEffect, useState } from "react";
import StoryblokClient from "storyblok-js-client";
const Storyblok = new StoryblokClient({
accessToken: process.env.STORYBLOK_API_KEY,
cache: {
clear: "auto",
type: "memory"
}
});
export function useStoryblok(originalStory, preview) {
let [story, setStory] = useState(originalStory);
// adds the events for updating the visual editor
// see https://www.storyblok.com/docs/guide/essentials/visual-editor#initializing-the-storyblok-js-bridge
function initEventListeners() {
const { StoryblokBridge } = window;
if (typeof StoryblokBridge !== "undefined") {
// initialize the bridge with your token
const storyblokInstance = new StoryblokBridge();
// reload on Next.js page on save or publish event in the Visual Editor
storyblokInstance.on(["change", "published"], () =>
location.reload(true)
);
// live update the story on input events
storyblokInstance.on("input", event => {
if (story && event.story.content._uid === story.content._uid) {
setStory(event.story);
}
});
storyblokInstance.on("enterEditmode", event => {
// loading the draft version on initial enter of editor
Storyblok.get(`cdn/stories/${event.storyId}`, {
version: "draft"
})
.then(({ data }) => {
if (data.story) {
setStory(data.story);
}
})
.catch(error => {
console.log(error);
});
});
}
}
// appends the bridge script tag to our document
// see https://www.storyblok.com/docs/guide/essentials/visual-editor#installing-the-storyblok-js-bridge
function addBridge(callback) {
// check if the script is already present
const existingScript = document.getElementById("storyblokBridge");
if (!existingScript) {
const script = document.createElement("script");
script.src = "//app.storyblok.com/f/storyblok-v2-latest.js";
script.id = "storyblokBridge";
document.body.appendChild(script);
script.onload = () => {
// once the scrip is loaded, init the event listeners
callback();
};
} else {
callback();
}
}
useEffect(() => {
// only load inside preview mode
if (preview) {
// first load the bridge, then initialize the event listeners
addBridge(initEventListeners);
}
}, [initEventListeners, preview]);
return story;
}
export default Storyblok;
提前致谢