Part 55: Enhancing Your Next.js Application: Fetching and Displaying CMS Data

[App] Headless CMS

[App] Headless CMS

In modern web development, leveraging a CMS (Content Management System) like Strapi can significantly enhance your application's flexibility and dynamism. In this blog post, we'll delve into the process of reimplementing the getReviews function to fetch comprehensive review data from Strapi. By the end, our Reviews page will be fully functional, displaying data dynamically fetched from the CMS.

Extending the getReviews Function

Previously, our getReviews function returned review objects with only slug and title. Now, we aim to include additional properties such as date and image.

Adding the Date Property

In our old code, we used a date property. The CMS, however, provides a publishedAt attribute. We'll use this attribute, but first, we need to ensure it matches the format required by our application.

  1. Extract the Date: The publishedAt attribute from Strapi includes both date and time. Since we only need the date, we'll slice the string to extract the year, month, and day:

    date: attributes.publishedAt.slice(0, 'yyyy-mm-dd'.length),

    This approach assumes the publishedAt string is in ISO format, which is a standard practice.

Adding the Image Property

Images in Strapi are often stored as nested objects. To extract the image URL, we'll navigate through these nested attributes:

  1. Access the Image URL: Extract the url from the nested image object:

    image: CMS_URL + attributes.image.data.attributes.url,

    This line constructs an absolute URL by prefixing the CMS address, ensuring the browser loads images correctly from the CMS.

Handling Image URLs

By default, the browser attempts to load images from the same domain as the web page. Since our images reside in the CMS, we need to adjust the URLs accordingly:

  1. Define a CMS URL Constant: At the top of your reviews.js file, define the base URL for your CMS:

    const CMS_URL = 'http://localhost:1337';
  2. Update Fetch URLs: Use template literals to construct the fetch URL, ensuring consistency and readability:

    const url = `${CMS_URL}/api/reviews?` + qs.stringify({...});

Finalizing the getReviews Implementation

The updated getReviews function now looks like this:

export async function getReviews() {
  const url = `${CMS_URL}/api/reviews?` + qs.stringify({
    fields: ['slug', 'title', 'subtitle', 'publishedAt'],
    populate: { image: { fields: ['url'] } },
    sort: ['publishedAt:desc'],
    pagination: { pageSize: 6 },
  }, { encodeValuesOnly: true });

  const response = await fetch(url);
  const { data } = await response.json();

  return data.map(({ attributes }) => ({
    slug: attributes.slug,
    title: attributes.title,
    date: attributes.publishedAt.slice(0, 'yyyy-mm-dd'.length),
    image: CMS_URL + attributes.image.data.attributes.url,
  }));
}

This function fetches data from the CMS, transforms it into a format suitable for our application, and returns an array of review objects.

Conclusion

By reimplementing the getReviews function, we've successfully integrated data fetching from Strapi into our Next.js application. This not only makes our Reviews page dynamic but also allows for easy content management via the CMS. The separation between data fetching and presentation ensures that our application remains flexible and maintainable.

In future updates, we'll tackle fetching individual review data, further enhancing the application's capabilities. Stay tuned as we continue to refine and expand our web application!

Last updated