Svelte rejects this syntax:
// conditional open link tag
{#if whatever}
<a href="myurl">
{/if}
//
// many lines of code for dynamic text output
//
// conditional close link tag
{#if whatever}
</a>
{/if}
Svelte's compiler throws: ParseError: Unexpected block closing tag
on the first conditional block, because it sees a <a>
without a matching </a>
.
This is a common need: something may need to become a hyperlink in some conditions but not in others, and the content within is far too complex to copy-paste so that it appears twice. I suppose the same thing could come up with any other html tag with opening and closing tags, where one wishes to conditionally add an html wrapper around something.
Certainly one could accomplish this either by creating a conditional component for every kind of html tag and slotting the inner code, or by moving the inner content to a function and injecting it into the DOM with {@html...}
, but these are ungainly solutions for something so incredibly basic and simple.
This just seems like something the framework should provide. Is there a clean way to do this?
For this specific case the solution is simple: Just always use an <a>
and make the href
conditional (a string or undefined
). An <a>
is not a link unless it actually has an href
.
In general, you can create a generic wrapper component like this:
<script>
export let element;
export let condition;
</script>
{#if condition}
<svelte:element this={element} {...$$restProps}>
<slot />
</svelte:element>
{:else}
<slot />
{/if}
<Wrapper element="a" condition={...}>
<!-- contents -->
</Wrapper>