DEV Community

lucas-brdt268
lucas-brdt268

Posted on

Headless Adventures: From CMS to Frontend Without Losing Your Mind (3)

🎨 Frontend Rendering Magic: Building Dynamic Pages From CMS Data (Without Crying)

So, you’ve fetched your shiny CMS data, mapped it beautifully, and you’re feeling powerful.
Then you try to render it on the frontend, and suddenly...
💥 “TypeError: Cannot read properties of undefined (reading 'map')”

Welcome to the glamorous life of frontend developers.


🧠 Scene 1: The Dream

You imagine a perfect world where your CMS sends this:

[
  { "title": "Post 1", "slug": "post-1" },
  { "title": "Post 2", "slug": "post-2" }
]
Enter fullscreen mode Exit fullscreen mode

and your frontend smoothly renders:

{posts.map(post => <PostCard title={post.title} />)}
Enter fullscreen mode Exit fullscreen mode

It works. You deploy. You smile. Life is good. ☀️


💀 Scene 2: The Reality

Two days later, your content editor adds a new “Featured” section in the CMS.
Now the response looks like:

{
  "posts": [
    { "title": "Post 1", "slug": "post-1" },
    { "title": "Post 2", "slug": "post-2" }
  ],
  "featured": null
}
Enter fullscreen mode Exit fullscreen mode

You reload your page.
💣 “Cannot read properties of null (reading 'map')”

Your perfect app now screams louder than your coffee machine on Monday. ☕😩


🛠️ Step 1: Always Guard Your Maps

It’s 2025. If you’re still doing data.map(), you’re basically coding without a seatbelt.
Do this instead:

{data?.length > 0 ? (
  data.map(item => <PostCard key={item.slug} {...item} />)
) : (
  <p>No posts found 😭</p>
)}
Enter fullscreen mode Exit fullscreen mode

Or go fancier:

{Array.isArray(data) && data.length ? (
  data.map(renderPost)
) : (
  <EmptyState message="Nothing to show, just vibes ✨" />
)}
Enter fullscreen mode Exit fullscreen mode

🎭 Step 2: The “Dynamic Page” Drama

You fetch your post list and want to render individual post pages dynamically.
If you’re using Next.js, you’ll go through the famous phase:

“Wait, getStaticPaths… getStaticProps… getServerSideProps… which one again!?” 😵‍💫

Simplify it:

// pages/[slug].js
export async function getStaticPaths() {
  const posts = await fetchPosts();
  return {
    paths: posts.map(post => ({ params: { slug: post.slug } })),
    fallback: 'blocking',
  };
}

export async function getStaticProps({ params }) {
  const post = await fetchPostBySlug(params.slug);
  return { props: { post }, revalidate: 60 };
}
Enter fullscreen mode Exit fullscreen mode

Boom.
You’ve just mastered SSG + ISR with one caffeine shot. ☕⚡


🧩 Step 3: Componentize Like a Legend

If your CMS has sections like “Hero”, “Gallery”, “Testimonials” — don’t hardcode them.
Instead, use a component resolver pattern:

const componentMap = {
  hero: HeroSection,
  gallery: GallerySection,
  testimonials: TestimonialsSection,
};

export default function Page({ blocks }) {
  return (
    <>
      {blocks?.map((block, i) => {
        const Component = componentMap[block.type];
        if (!Component) return <p key={i}>🤔 Unknown block: {block.type}</p>;
        return <Component key={i} {...block} />;
      })}
    </>
  );
}
Enter fullscreen mode Exit fullscreen mode

Now when your CMS team adds a new section called “weird-experimental-banner”,
you just add a component and roll with it. 😎


🐞 Step 4: Handle CMS “Creativity” Gracefully

There will be times when your CMS data…
doesn’t make sense.

Like this:

{ "hero": { "title": null, "image": 1234, "button": "Read more" } }
Enter fullscreen mode Exit fullscreen mode

So, guard your rendering logic like a bouncer at a nightclub:

{hero?.title ? (
  <Hero title={hero.title} image={hero.image} />
) : (
  <FallbackHero message="This hero is shy today 😅" />
)}
Enter fullscreen mode Exit fullscreen mode

Your users won’t see chaos — only charm. 💅


🚀 Step 5: Deploy and Brag

Once it all works, deploy it on Dockploy (or your platform of choice).
Bonus points if you act like it was easy in front of your team:

“Yeah, dynamic routing with CMS content? Took like 10 minutes.” 😏
(Meanwhile, your commit history looks like a battlefield.)


🧘‍♂️ TL;DR

  1. Guard your data before you render it.
  2. Use component mapping for dynamic sections.
  3. Learn your rendering methods (SSR, SSG, ISR — they’re not just buzzwords).
  4. Handle weird CMS data with humor, not panic.
  5. Deploy with pride, even if it took three breakdowns and a nap.

Top comments (1)

Collapse
 
priyanayak profile image
priyanayak

I’ve been working with evaluation workflows for LLM outputs, and this open-source SDK has been useful for standardizing scoring across text, image, and audio tasks:

Start here →
GitHub Repo:

https://github.com/future-agi/ai-evaluation

Enter fullscreen mode Exit fullscreen mode

If it helps, add a ⭐ here → [

https://github.com/future-agi/ai-evaluation

Enter fullscreen mode Exit fullscreen mode

The examples folder in the repo is particularly helpful — it shows real evaluation templates and how they apply in different use cases.

Curious to hear how others here approach evaluation in their own pipelines.