#Generate pages from headless CMS without webhook

1 messages · Page 1 of 1 (latest)

vivid cape
#

I'm using a headless CMS that does not offer webhooks on the plan I am on. I'd like to generate pages programatically and have them auto update once content changes

But I can't seem to do that without webhooks, my only option seems to be ISR with a short timer (like 1 minute between each update). But this to me seems almost like having fully dynamic pages that fetch everything every request as many of the pages will have way fewer than one person per minute, so each person visiting will essentially experience a fresh load of a page

I get my data using GraphQL and currently just do one page.tsx per CMS page, any suggestions on how you would do this? 🤔

glad abyssBOT
#

Hi @vivid cape. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

Based on the information provided in the extracts, Incremental Static Regeneration (ISR) seems to be the best solution for your use case. ISR allows you to create or update static pages after you've built your site, without needing to rebuild the entire site. This means you can retain the benefits of static while scaling to millions of pages.

You can use ISR by adding the revalidate prop to getStaticProps. Here's an example:

export async function getStaticProps() {
 const res = await fetch('<https://.../posts'>)
 const posts = await res.json()
 
 return {
 props: {
 posts,
 },
 // Next.js will attempt to re-generate the page:
 // - When a request comes in
 // - At most once every 10 seconds
 revalidate: 10, // In seconds
 }
}

In this example, Next.js will attempt to re-generate the page when a request comes in, at most once every 10 seconds. You can adjust the revalidate time to suit your needs.

However, you mentioned that you're concerned about the pages being regenerated too frequently, essentially making them dynamic. It's important to note that with ISR, pages are regenerated in the background, and the "stale" page is served until the regeneration is complete. This means that even if a page is being regenerated every minute, users will still be served the page instantly, as if it were a fully static page.

If you're using Vercel, you can also take advantage of their ISR Render Functions (https://vercel.com/docs/concepts/next.js/incremental-static-regeneration#isr-render-function) for improved security and better performance.

#

@vivid cape kapa.ai is still learning and improving, please let us know how it did by reacting below

vivid cape
#

@glad abyss I want to to use this in a [slug].tsx file so that I can generate all the pages from my CMS data. will this work in a [slug].tsx file?

glad abyssBOT
#

Let me check the knowledge base for you. One moment! :books:

#

Yes, you can use ISR in a [slug].tsx file. This is particularly useful when you want to generate multiple pages based on data from your CMS.

You can use the getStaticPaths function to pre-render all the paths at build time. If a path doesn't exist, it will be server-rendered on-demand with the { fallback: 'blocking' } option. Here's an example:

export async function getStaticPaths() {
 const res = await fetch('<https://.../posts'>)
 const posts = await res.json()
 
 // Get the paths we want to pre-render based on posts
 const paths = posts.map((post) => ({
 params: { id: post.id },
 }))
 
 // We'll pre-render only these paths at build time.
 // { fallback: 'blocking' } will server-render pages
 // on-demand if the path doesn't exist.
 return { paths, fallback: 'blocking' }
}

In this example, getStaticPaths fetches the posts from your CMS and returns an array of paths to be pre-rendered. If a visitor navigates to a path that hasn't been generated, Next.js will server-render the page on-demand.

For more information on how to use getStaticPaths with ISR, you can refer to the Next.js documentation (https://nextjs.org/docs/pages/building-your-application/rendering/incremental-static-regeneration).

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@vivid cape kapa.ai is still learning and improving, please let us know how it did by reacting below

vivid cape
#

@glad abyss The nextjs docs uses both getStaticProps() and getStaticPaths() in the same file, your example does not. Should I use both?

glad abyssBOT
#

Let me check the knowledge base for you. One moment! :books:

#

Yes, you should use both getStaticProps and getStaticPaths in your [slug].tsx file when you're generating static pages from dynamic routes.

getStaticPaths is used to specify which paths for the dynamic route should be pre-rendered at build time. If a path is not pre-rendered at build time, it can be server-rendered on-demand with the { fallback: 'blocking' } option.

getStaticProps is used to fetch the data for each individual page. It runs at build time in production and will receive the parameters defined in getStaticPaths.

Here's an example of how you can use both in your [slug].tsx file:

export async function getStaticPaths() {
 const res = await fetch('<https://.../posts'>)
 const posts = await res.json()
 
 // Get the paths we want to pre-render based on posts
 const paths = posts.map((post) => ({
 params: { id: post.id },
 }))
 
 // We'll pre-render only these paths at build time.
 // { fallback: 'blocking' } will server-render pages
 // on-demand if the path doesn't exist.
 return { paths, fallback: 'blocking' }
}

export async function getStaticProps({ params }) {
 const res = await fetch(`<https://.../posts/${params.id}`>)
 const post = await res.json()
 
 return {
 props: {
 post,
 },
 // Next.js will attempt to re-generate the page:
 // - When a request comes in
 // - At most once every 10 seconds
 revalidate: 10, // In seconds
 }
}

function Blog({ post }) {
 return (
 <div>
 <h1>{post.title}</h1>
 <p>{post.content}</p>
 </div>
 )
}

export default Blog

In this example, getStaticPaths fetches the posts from your CMS and returns an array of paths to be pre-rendered. Then, getStaticProps fetches the data for each individual post based on the id parameter.

#

@vivid cape kapa.ai is still learning and improving, please let us know how it did by reacting below

vivid cape
#

@glad abyss do I have to use ID in getStaticPaths? is using params: { slug: SLUGNAME} valid?
const paths = page.data.allTjenester.edges.map((page) => ({
params: { id: urlToSlug(page.node.url)},
}))

glad abyssBOT
#

Let me check the knowledge base for you. One moment! :books:

#

Yes, you can definitely use slug instead of id in getStaticPaths. The params object keys should match the dynamic parts of your page path. So if your page path is [slug].tsx, you should use slug as the key in your params object. Here's how you can do it:

const paths = page.data.allTjenester.edges.map((page) => ({
  params: { slug: urlToSlug(page.node.url) },
}))

In this example, each slug corresponds to a path that should be pre-rendered. For instance, if one of your slugs is 'post-1', Next.js will statically generate a page at /post-1.

For more information on how to use getStaticPaths, you can refer to the Next.js documentation (https://nextjs.org/docs/pages/building-your-application/data-fetching/get-static-paths).

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@vivid cape kapa.ai is still learning and improving, please let us know how it did by reacting below

vivid cape
#

I can't find the testpage I created in the CMS and I can't see the result of console.log when I run the page and try to access my testpage
What coudl the issue be? How can I see console.logs?

#

@glad abyss I can't find the testpage I created in the CMS and I can't see the result of console.log when I run the page and try to access my testpage
What coudl the issue be? How can I see console.logs?

import { getAllServices } from "@/lib/fetchData";
import { urlToSlug } from "@/lib/urlToSlug";
import type { PageBuilderProps } from "src/components/pagebuilder";
type AuditCustomer = {
node: {
name: string;
utforteOppdrag: string[];
url: string;
id: string;
};
};
type Page = {
allGranskningskunde: {
edges: AuditCustomer[];
};
content: {
level: number;
url: string;
id: string;
name: string;
sidebygger?: PageBuilderProps[];
};
};

type PageLinks = {
data: {
allTjenester: {
edges: {
node: {
name: string;
url: string;
id: string;
};
}[];
};
};
};

function PageTemplate({ props }: { props: string }) {
console.log("Props er", props);
return <div>Hello world </div>;
}

// This function gets called at build time on server-side.
// It may be called again, on a serverless function, if
// revalidation is enabled and a new request comes in
export async function getStaticProps() {
// const res = await fetch('https://.../posts')
const page = (await getAllServices()) as PageLinks;
console.log("getStaticProps", page);

return {
props: {
page,
},

revalidate: 10, // In seconds

};
}

export async function getStaticPaths() {

const page = (await getAllServices()) as PageLinks;
console.log("getStaticPaths", page);

const paths = page.data.allTjenester.edges.map((page) => ({
params: { slug: urlToSlug(page.node.url) },
}));

return { paths, fallback: "blocking" };
}

export default PageTemplate;

glad abyssBOT
#

Let me check the knowledge base for you. One moment! :books:

#

If you can't find the test page you created in the CMS, there could be a few reasons:

  1. The page might not have been published in your CMS. Make sure the page is published and not in a draft or unpublished state.
  2. The getAllServices function might not be fetching the correct data. Make sure this function is correctly fetching all the pages from your CMS.
  3. The urlToSlug function might not be correctly converting the URL to a slug. Make sure this function is working as expected.

As for not being able to see the result of console.log, there are a few things to note:

  1. console.log in getStaticProps and getStaticPaths will not be displayed in the browser console. These functions run at build time on the server-side, so their logs will appear in your terminal where you run your build command.

  2. If you're deploying your application on Vercel, you can view these logs in the Vercel dashboard. They can be accessed by selecting either "View Build Logs" or "View Function Logs" from the Project page (source (https://vercel.com/guides/where-are-vercel-logs)).

  3. console.log in your PageTemplate component will be displayed in the browser console as this component is rendered on the client-side.

If you're still having trouble, you might want to consider debugging your application. You can debug server-side code with Chrome DevTools by passing the --inspect flag to the underlying Node.js process (source (https://nextjs.org/docs/pages/building-your-application/configuring/debugging)). For client-side code, you can use Chrome's Developer Tools (source (https://nextjs.org/docs/pages/building-your-application/configuring/debugging)).

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@vivid cape kapa.ai is still learning and improving, please let us know how it did by reacting below

vivid cape
#

@glad abyss getting error "
"getStaticProps" is not supported in app/." with the code you sent

glad abyssBOT
#

Let me check the knowledge base for you. One moment! :books: