0

I am fetching some data from my CMS and got stuck trying to initialize a component i get as a string.

These are my components as a string array:

[
  '<Header text="title1" img="link/to/image1" />',
  '<Header text="title2" img="link/to/image2" />'
]

I could not find any way to init those strings as components in astro. Is this even possible? Also, i am not using any frontend framework integrations atm

Thanks in advance!

stepframe
  • 11
  • 3
  • I don’t think there’s a built-in way to do this. If the strings were just raw HTML, you could use the `set:html` directive, but if you need to invoke a component that wouldn’t work. Can you get the CMS to send you a more structured data version of this? Like `{ component: 'Header', props: { text: 'title1' } }`? – swithinbank Aug 27 '23 at 08:30
  • Hi @swithinbank , thanks for your reply :) yes, thats pretty much what i originally get from my CMS. Do you think that makes it possible to create Components with? – stepframe Aug 27 '23 at 09:24

2 Answers2

0

As a Follow-Up:

As could not find any way to do this in vanilla astro, I now use the svelte integration to do create components dynamically.

In svelte, I can do something like this:

{#each pageData as element}
    {#if element["element-type"] === "header"}
        <Header content={element["content"]} />
    {/if}
{/each}
stepframe
  • 11
  • 3
0

Sounds like you have access to a structured data about your components from your CMS. I’m going to assume this looks like this:

[
  { component: 'Header', props: { text: 'title1', img: 'link/to/image1' } },
  { component: 'Footer', props: { text: 'title2', img: 'link/to/image2' } },
]

If you have this, you can do something like the following:

---
// 1. Import each component you might need.
import Header from '../components/Header.astro';
import Footer from '../components/Footer.astro';

// 2. Create an object to use to look up your components.
const components = { Header, Footer };

const cmsData = getCmsData(); // Pseudo code for whatever gets you your data.
---

{cmsData.map(({ component, props }) => {
  // 3. Use the object to look up your components.
  const Component = components[component];
  return <Component {...props} />
})}

This is based on the basic Dynamic Tags example in the Astro docs.

swithinbank
  • 1,127
  • 1
  • 6
  • 15