1

I have a simple PrimaryButton.svelte component that contains "HTML" only (no script or style tags) and looks like this:

<button class="btn-primary btn accent--br">Primary button</button>

Then I imported the component into App.svelte and it renders in the browser just fine, but I also want to show the HTML code of the component as well.

App.svelte looks like this:

<script>
    import PrimaryButton from "./components/Buttons/PrimaryButton.svelte";
</script>

<PrimaryButton/>

I tried to render it as a string like this: {PrimaryButton} instead of <PrimaryButton/>. But the browser displayed this string:

class PrimaryButton extends SvelteComponentDev { constructor(options) { super(options); init(this, options, instance$5, create_fragment$5, safe_not_equal, {}); dispatch_dev("SvelteRegisterComponent", { component: this, tagName: "PrimaryButton", options, id: create_fragment$5.name }); } }

I was kind of hoping it would show the HTML of the component as a string instead but I do sort of understand why that's not happening.

How can I show the output HTML of the component as a string in the browser? What would you do?

3 Answers 3

5

You can use the outerHTML attribute of DOM element.

// PrimaryButton.svelte
<script>
let element;
export let code = "";
onMount(() => {
  code = element.outerHTML
})
</script>

<button bind:this={element} class="btn-primary btn accent--br" href="#">Primary button</button>


// App.svelte
<script>
import PrimaryButton from "PrimaryButton.svelte"

let PrimaryButtonCode;
</script>

<pre>{PrimaryButtonCode}</pre>
<PrimaryButton bind:code={PrimaryButtonCode} />
Sign up to request clarification or add additional context in comments.

4 Comments

I don't want to console log it, I want to show it on the web page along side the rendered button. Am I not understanding something from your answer?
Ok, I sort of figured it out... But not exactly what I want yet. Thanks for your answer
I must point out, there’s no way to get that HTML string without instantiating the component in the first place. Guess you must’ve realized, the component is pure JS, the HTML "template" is encoded in JS, it doesn’t exist anywhere before executing the JS code.
I ended up doing something completely different because it works better for my use case (see my answer). However I do appreciate your answer and I think it is a legitimate way of doing it as well. Just started learning svelte so don't know much yet.
1

I ended up defining .html files instead and then importing them into svelte components using this plugin: https://www.npmjs.com/package/rollup-plugin-string

In the svelte component I can either render the HTML or show the string of the HTML code:

<script>
    import button from "./button.html";
</script>

{button}

{@html button}

Comments

1

The other answers either show the rendered output immediately or need to actually render the component in your (visible) DOM to be able to get the rendered html.
This answer will explain how to get the html:

  • without having to render it in the DOM the user sees.
  • In a variable, so you can use it in other ways afterwards.

The way to do this differs whether you're using plain Svelte or the SvelteKit backend to render the component to a string. I'll show an example for both ways.

Svelte

If I have this component:

<script lang="ts">
  export let name: string;
</script>
<button>Hello, {name}</button>

Then I can render it normally, and to a string variable like this:

<script lang="ts">
  import Hello from './lib/Hello.svelte'
  const elem = document.createElement('div');
  new Hello({ target: elem, props: { name: 'Jeroen' } });
  const strHello = elem.innerHTML;
</script>

<main>
  <Hello name="Jeroen" />
  {strHello}
</main>

In essence what we're doing is:

  • Creating a (non-visible) DOM element on the fly
  • Telling our Svelte component to render inside that dom element
  • Getting the rendered HTML out of that DOM element

SvelteKit

In the SvelteKit backend this works a bit differently because we don't have a DOM to work with.
When you import a component in the SK backend it will also have a different structure than when you import it in the frontend.

The imported value will have a render function defined on it.
It will also accept the props of the component as a parameter.
You can use it like this:

import type { Load } from "@sveltejs/kit";
import Hello from '$lib/Hello.svelte';

export const load: Load = async ({  }) => {
  const result = (Hello as any).render({ name: "Jeroen" });
  console.log(result.html);
  console.log(result.css.code);
};

result.html will contain the rendered html for the component and result.css.code will contain the processed css code that was in your style tag. (this css is also scoped to the component)

Making it typesafe

In the example above I did a cast to any to quickly show an example. If you want the props to be typesafe you can read this blog post that explains how to render a Svelte component to a string in a typesafe manner: https://jeroenpelgrims.com/render-svelte-component-to-string/

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.