Dynamic Blog Article using Next.JS

In this Forum post, I’ll explain how to create a dynamic blog post using Next.js.
This Paradigm can be applied to any framework.

1-Blog section template
Create a section model for the blog template.
Add the slug preview and give it a default value.
Add the Article preview and give it a default value referencing an Article.
Make the Preview URL dynamically generated .

return `http://localhost:3000/blog/${content.data.slugPreview}`

For more references on Dynamic Preview URLs, check out this document:

Create Your Blog Article Template UI using Builder.IO CMS

2- Article and Author model
→ Create Article and Author data model. Make sure to add ‘slug’ as a custom field in the
article model.

For a quick start, follow the blog article blueprint in The Builder website:

3- Create blog/[slug] for dynamic routing in Next.js
In Next.js app create your dynamic routing: blog/[slug]
Screenshot 2023-05-16 at 12.45.24 PM

3- Fetch blog template data and article data using [slug] as params at build time
Fetch the article data from the data model by querying the slug as the parameter.

export async function getStaticProps({ 
    params 
}: GetStaticPropsContext<{ slug: string[] }>) {
   const articleData =  
    (await builder
        .get('article',{
        query:{
            'data.slug': params?.slug
        }
     }).toPromise()) || null;

 const articleTemplate = await builder
    .get('blog-template', {
        options: {
            enrich: true,
        },
    }).toPromise();

  return {
    props: {
        articleData,
        articleTemplate   
    },
    revalidate: 5,
  };
}

5- Pre-render the Dynamic routes using getStaticPaths()

fetch all the articles using builder.getAll(model)

export async function getStaticPaths() {
  const articles = await builder.getAll('article', {
    options: {noTargeting: true},
    omit: 'data.blocks'
  })

  articles.map(article => console.log(`/blog/${article.data?.slug}`),)
  
  return {
    paths : articles.map(article => `/blog/${article.data?.slug}`),
    fallback: true,
  };
}

6- Render <BuilderComponent /> using blog template populated by the article data

On The client Side, get the blog template and populate it with article data queried using slug.

export default function Page({
     articleTemplate ,
     articleData
    }:InferGetStaticPropsType<typeof getStaticProps>) {
  const router = useRouter();
  if (router.isFallback) {
    return <h1>Loading...</h1>;
  }
  const isLive = !Builder.isEditing && !Builder.isPreviewing;

  if (!articleData && isLive) {
    return (
      <>
        <Head>
          <meta name="robots" content="noindex" />
          <meta name="title"></meta>
        </Head>
        <DefaultErrorPage statusCode={404} />
      </>
    );
  }

  return (
    <>
      <Head>
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        {!articleData && <meta name='robots' content='noindex'/>}
      </Head>
       <BuilderComponent model="blog-template" 
                content={articleTemplate} 
                data={{article: articleData?.data}} 
        />
    </>
  );
}

The end result

Thanks for sharing your knowledge! As a beginner, I especially appreciate the screenshot and video.

Some feedback:

I personally tapped out here. I wouldn’t know what to do. What blog template? What section template? Are we starting from scratch? Where is my model? Where do I go? Give me a sign.

I would also love to understand the concept of a dynamic preview URL a little better (as opposed to a static one). I’ve posted a thread asking about it here but I still don’t really get it. If You could elaborate a bit and explain what the preview URL gives us over a static one in this use case I would be elated.

Hi I know this is a late response but, what you need to do in step one is create a Section Model called “blog-template” and add fields slugPreview (type: text) and articlePreview (type: reference). After you’ve created the model, create an entry using the blog-template model you just made and give it a dynamic url using this javascript:

return `http://localhost:3000/blog/${content.data.slugPreview}`

What this does is populates the preview url with the value from the section’s slugPreview field and allows you to preview articles with specific slugs in the visual editor.

Hopefully you should be able to finish the example with this information. If you have any other questions feel free to respond here.