Search code examples
htmlsveltesveltekit

Having trouble rendering html text in Svelte with @html


right now i have some html contained in an object inside of a svelte component. I am using svelte kit if that matters.

let htmlString = "";

I have an api that gives me some html and assigns it to the htmlString variable. here is an example of what that would look like:

<h1>Neural Network Classification (from-scratch)</h1>

<h2>Parameters</h2>

<p>Think of epochs as rounds of training for your neural network. Each epoch means the network has gone through the entire dataset once, learning and adjusting its parameters. More epochs can lead to better accuracy, but too many can also overfit the model to your training data.</p>

<h4>Activation functions</h4>

and then I have the code below that should be rendering the html.

<div>
    {@html htmlString}
</div>

However, the component is just displaying the raw text. For example the h1 tag is not applied for some reason, and neither is any other tag, only the plain text.

if it helps, here is how I am calling the API from the front end inside of this component:

<script lang="ts">
  import { Card } from "flowbite-svelte";
  import { onMount } from "svelte";

  export let readmeUrl: string = "";
  let readmeContent;

  async function fetchReadme() {
    try {
      const response = await fetch(
        `api_endpoint`,
      );
      if (response.ok) {
        readmeContent = await response.text();
        console.log(readmeContent)
      } else {
        readmeContent = null;
      }
    } catch (error) {
      readmeContent = null;
    }
  }

  onMount(fetchReadme);
</script>

any help is appriciated, thanks!


Solution

  • Since you're using Flowbite-Svelte, you're probably getting this behavior because of Tailwind's [Preflight][1]. Elements are unstyled by default. You can wrap your {@html} in a parent div and define a class that you'll use customize the inner content in CSS so it's styled the way you'd want.

    In your HTML where you're displaying {@html}

    <div class="renderedHTML">
        {@html htmlString}
    </div>
    

    In your app.css / app.post.css

    
    @tailwind base;
    @tailwind components;
    @tailwind utilities;
    
    /* Your custom styles for @html content with parent div class renderedHTML */
    .renderedHTML h1 {
        @apply text-2xl;
    }
    .renderedHTML h2 {
        @apply text-xl;
    }
    

    You can also extend preflight universally through your web app but I've found this to be accident prone.

    @tailwind base;
    
    @layer base {
      h1 {
        @apply text-2xl;
      }
      h2 {
        @apply text-xl;
      }
    }
    
    @tailwind components;
    
    @tailwind utilities;