storyblok / storyblok-react

React SDK for Storyblok CMS
MIT License
121 stars 36 forks source link

StoryblokApi fails at fetching stories at times #1254

Open moarief opened 7 months ago

moarief commented 7 months ago

Using the storyblokApi.get() method to fetch a story sometimes returns an error, which causes the site to crash as there is no data at all. Not sure why this happens as I have tested with a regular fetch call to the storyblok endpoint, which works without issues.

I am using NextJS 14.1.3 for this project and "@storyblok/react": "3.0.8".


Expected Behavior

When using the storyblokApi.get() method the data should be returned as:

{
  data:
    {
      story:
        {
          name: "Home",
          created_at: "2023-11-05T21:44:18.182Z",
          published_at: "2024-03-06T22:21:10.045Z",
          id: 401385259,
          uuid: "4f169ba7-af0d-4313-bac0-317fa0efd5a2",
          content: [Object],
          slug: "home",
          full_slug: "home",
          sort_by_date: null,
          position: 0,
          tag_list: [],
          is_startpage: false,
          parent_id: 0,
          meta_data: null,
          group_id: "5674ea5f-1f80-43d6-a29b-80fa827cae3c",
          first_published_at: "2023-11-06T20:22:49.785Z",
          release_id: null,
          lang: "default",
          path: "/",
          alternates: [],
          default_full_slug: null,
          translated_slugs: null,
        },
      cv: 1709842725,
      rels: [],
      links: [],
    },
}

Current Behavior

Local testing:

Error fetching data:  {
   message: 'Not Found',
   status: 404,
   response: 'This record could not be found'
}

Production environment:

image

Steps to Reproduce

This is my current storyblok.ts setup for getting stories, links etc.:

import { apiPlugin, storyblokInit } from '@storyblok/js';

import { INavigation, INavigationItem, NavigationData, NestedPages, Slug } from './types';

const storyblokToken =
  process.env.NODE_ENV === "development"
    ? process.env.NEXT_PUBLIC_DRAFT_SECRET_TOKEN
    : process.env.NEXT_PUBLIC_STORYBLOK_TOKEN;

console.log("🚀 ~ process.env.NODE_ENV:", process.env.NODE_ENV);

const { storyblokApi } = storyblokInit({
  accessToken: storyblokToken,
  bridge: process.env.NODE_ENV !== "production",
  apiOptions: {
    region: "eu",
    cache: {
      clear: "auto",
      type: "memory",
    },
  },
  use: [apiPlugin],
});

// Function to remove an object based on a specific property value
function removeObjectBySlug(linksObject: any, targetSlug: string) {
  for (const key in linksObject) {
    if (
      linksObject.hasOwnProperty(key) &&
      linksObject[key].slug === targetSlug
    ) {
      delete linksObject[key];
      break;
    }
  }
}

export async function getLinks() {
  if (!storyblokApi) {
    return;
  }

  const { data } = await storyblokApi.get("cdn/links", {
    version: process.env.NEXT_PUBLIC_STORYBLOK_VERSION as "draft" | "published",
  });

  const links = data ? data.links : null;

  // Remove special links
  removeObjectBySlug(links, "social-media");

  return links;
}

export async function getStory(slug: string) {
  if (!storyblokApi) {
    return;
  }

  let story;

  try {
    const { data } = await storyblokApi.get(`cdn/stories/${slug}`, {
      version: process.env.NEXT_PUBLIC_STORYBLOK_VERSION as
        | "draft"
        | "published",
    });

    // Continue processing data
    story = data ? data.story : null;
  } catch (error) {
    // Log or handle the error
    console.error("Error fetching data: ", error);
  }

  return story;
}

If I change the getStory method use a regular fetch method instead I do not get this issue:

export async function getStory(slug: string) {
  /* if (!storyblokApi) {
    return;
  } */

  let story;

  try {
    /* const { data } = await storyblokApi.get(`cdn/stories/${slug}`, {
      version: process.env.NEXT_PUBLIC_STORYBLOK_VERSION as
        | "draft"
        | "published",
    }); */

    const url = `https://api.storyblok.com/v2/cdn/stories/${slug}?version=${process.env.NEXT_PUBLIC_STORYBLOK_VERSION}&token=${storyblokToken}`;
    /**
     * 600 = 10 min
     * 3600 revalidate at most every hour
     */
    let req = await fetch(url, { next: { revalidate: 600 } });

    const storyData = await req.json();
    // console.log("🚀 ~ getStory ~ storyData:", storyData)

    // Continue processing data
    story = storyData ? storyData.story : null;
  } catch (error) {
    // Log or handle the error
    console.error("Error fetching data: ", error);
  }

  return story;
}
alvarosabu commented 1 week ago

I'm transferring this ticket to the react sdk