Part 56: Enhancing Our Review Pages with Strapi in Next.js

[App] Headless CMS

[App] Headless CMS

In the world of modern web development, integrating a Content Management System (CMS) like Strapi with your Next.js application can greatly enhance content flexibility and streamline the development process. In this post, we will guide you through the process of refactoring a Next.js application to fetch individual review data directly from Strapi, overcoming the limitations of relying solely on local Markdown files.

Understanding the Current Setup

Previously, our application was set up to fetch a list of reviews from Strapi, displaying six reviews per page, each with its own title and image. However, when attempting to open an individual review page, the application attempted to load content from a local Markdown file. This approach led to errors when the desired review existed only in the CMS and not locally.

Transitioning from Local Files to CMS

The key to resolving this issue lies in rewriting the getReview function to pull data directly from Strapi. Let's walk through this transformation step by step.

Step 1: Testing the API Call

Before integrating an API call into our application, it's essential to test it separately to ensure it returns the desired data. Here's how you can do it:

  1. Prepare the API Request: Use the qs library to construct a query string that filters reviews by slug:

    const url = 'http://localhost:1337/api/reviews'
      + '?' + qs.stringify({
        filters: { slug: { $eq: 'hades-2018' } },
        fields: ['slug', 'title', 'subtitle', 'publishedAt', 'body'],
        populate: { image: { fields: ['url'] } },
        pagination: { pageSize: 1, withCount: false },
      }, { encodeValuesOnly: true });
  2. Execute the Request: Run the script to verify the response contains the correct data structure. This should return an array with a single review object matching the specified slug.

Step 2: Temporarily Disable Static Params Generation

To focus on getting the getReview function working, temporarily comment out the generateStaticParams function. This function is responsible for generating static pages in production, and by disabling it, you can test your changes in development without interference.

// export async function generateStaticParams() {
//   const slugs = await getSlugs();
//   return slugs.map((slug) => ({ slug }));
// }

Step 3: Implementing the Fetch in getReview

With the API call verified, we can now integrate it into our getReview function:

  1. Fetch Data from Strapi: Modify getReview to use the API request, filtering reviews by slug and selecting only the necessary fields:

    export async function getReview(slug) {
      const url = `${CMS_URL}/api/reviews?`
        + qs.stringify({
          filters: { slug: { $eq: slug } },
          fields: ['slug', 'title', 'subtitle', 'publishedAt', 'body'],
          populate: { image: { fields: ['url'] } },
          pagination: { pageSize: 1, withCount: false },
        }, { encodeValuesOnly: true });
    
      const response = await fetch(url);
      const { data } = await response.json();
    
      const { attributes } = data[0];
      return {
        slug: attributes.slug,
        title: attributes.title,
        date: attributes.publishedAt.slice(0, 'yyyy-mm-dd'.length),
        image: CMS_URL + attributes.image.data.attributes.url,
        body: marked(attributes.body),
      };
    }
  2. Restart the Development Server: After updating the code, restart your server to apply the changes:

    npm run dev

Step 4: Handle Dynamic Routing with slug

In Next.js, we utilize slug as a dynamic route parameter. Since the API request is designed to filter by slug, we replace hardcoded values with the dynamic slug received from the route.

Step 5: Render Markdown to HTML

The body fetched from Strapi is in Markdown format. To display it correctly, we use the marked library to render Markdown to HTML, ensuring that text formatting, such as bold and italic, appears correctly on the page.

Step 6: Verify and Clean Up

Once the new implementation is complete, test it by opening different reviews to ensure the data displays correctly, including all formatting. With everything working smoothly, you can remove any old commented-out code.

Conclusion

By refactoring the getReview function to fetch data from Strapi, our Next.js application can now dynamically retrieve individual reviews based on their slug. This change eliminates the dependency on local Markdown files and ensures that content is always current and consistent with the CMS.

This integration not only improves the flexibility of our application but also sets the stage for future enhancements and optimizations. Stay tuned for more insights as we continue to refine our CMS integration and explore new ways to enhance our application's capabilities.

Last updated