#Is possible to use a Switch Statement in an .astro file?

4 messages · Page 1 of 1 (latest)

frozen robin
#

Can I use a switch to replace the ? statements? ---
import { clsx } from 'clsx';
import { HeadingType, TextAlignment } from 'src/utils/sectionEnums';
interface Props {
headingType: HeadingType;
title?: string;
heading: string;
body?: string;
textAlignment?: 'left' | 'center' | 'right';
}

const {
headingType,
heading,
body,
title,
textAlignment = 'left',
} = Astro.props as Props;

// For backward compatibility
const isCenter = textAlignment === 'center';
const isRight = textAlignment === 'right';

<div
class={clsx(
'flex flex-col gap-4 max-w-4xl w-full',
isCenter && 'items-center text-center',
isRight && 'items-end text-right',
!isCenter && !isRight && 'items-start text-left'
)}

{
title && (
<span class="text-base font-bold text-orange-500 md:text-xl">
{title}
</span>
)
}
{
headingType === HeadingType.h1 ? (
<h1
class="text-4xl/8 font-bold md:text-5xl/12 lg:text-6xl/14"
set:html={heading}
/>
) : headingType === HeadingType.h2 ? (
<h2
class="xs:text-4xl/8 text-3xl/8 font-bold md:text-5xl/12"
set:html={heading}
/>
) : (
<h3 class="text-2xl font-bold" set:html={heading} />
)
}
{
body && (
<p class="xs:text-lg max-w-2xl text-base lg:text-xl" set:html={body} />
)
}
</div>

steady ploverBOT
#

Hi @frozen robin. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

Yes, you can use a switch statement in the frontmatter (the script section between the --- fences) of an .astro file. The frontmatter supports any valid JavaScript, including switch statements. However, you cannot use a switch statement directly inside the template (the HTML part) of your .astro file. In the template, you can only use JavaScript expressions, such as ternary operators and logical && for conditional rendering.

If you want to use a switch to determine which element to render (for example, to replace a chain of ternary operators), you should compute the result in the frontmatter and then use that variable in your template. Here’s how you could refactor your code:

---
import { clsx } from 'clsx';
import { HeadingType, TextAlignment } from 'src/utils/sectionEnums';
interface Props {
  headingType: HeadingType;
  title?: string;
  heading: string;
  body?: string;
  textAlignment?: 'left' | 'center' | 'right';
}

const {
  headingType,
  heading,
  body,
  title,
  textAlignment = 'left',
} = Astro.props as Props;

// For backward compatibility
const isCenter = textAlignment === 'center';
const isRight = textAlignment === 'right';
#

let headingElement;
switch (headingType) {
case HeadingType.h1:
headingElement = <h1 class="text-4xl/8 font-bold md:text-5xl/12 lg:text-6xl/14" set:html={heading} />;
break;
case HeadingType.h2:
headingElement = <h2 class="xs:text-4xl/8 text-3xl/8 font-bold md:text-5xl/12" set:html={heading} />;
break;
default:
headingElement = <h3 class="text-2xl font-bold" set:html={heading} />;
}

<div
class={clsx(
'flex flex-col gap-4 max-w-4xl w-full',
isCenter && 'items-center text-center',
isRight && 'items-end text-right',
!isCenter && !isRight && 'items-start text-left'
)}

{title && (
<span class="text-base font-bold text-orange-500 md:text-xl">
{title}
</span>
)}
{headingElement}
{body && (
<p class="xs:text-lg max-w-2xl text-base lg:text-xl" set:html={body} />
)}
</div>


This approach is supported and recommended for more complex conditional rendering, as described in the Astro documentation for dynamic modular content blocks, where a `switch` statement is used in the frontmatter to determine which component to render based on data from a CMS. The same pattern applies to your use case, just with elements instead of components [Adding Dynamic modular content blocks](<https://docs.astro.build/en/guides/cms/datocms/#adding-dynamic-modular-content-blocks>).

**Summary:**  
- Use `switch` statements in the frontmatter to set a variable to the desired JSX/HTML element.
- Use that variable in your template.
- You cannot use `switch` directly in the template, but ternaries and logical operators are allowed [Template expressions reference](<https://docs.astro.build/en/reference/astro-syntax/#jsx-like-expressions>).
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------