Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Astro.slots.render escaping HTML output #4818

Closed
1 task
delucis opened this issue Sep 20, 2022 · 4 comments · Fixed by #4819
Closed
1 task

Astro.slots.render escaping HTML output #4818

delucis opened this issue Sep 20, 2022 · 4 comments · Fixed by #4819
Assignees
Labels
- P4: important Violate documented behavior or significantly impacts performance (priority)

Comments

@delucis
Copy link
Member

delucis commented Sep 20, 2022

What version of astro are you using?

1.2.7

Are you using an SSR adapter? If so, which one?

n/a

What package manager are you using?

npm

What operating system are you using?

Stackblitz

Describe the Bug

We have an API for passing arguments to slot children if they are functions when using the Astro.slots.render, which I’m trying to document.

Expected behaviour

The whole process looks something like this:

  1. A component uses Astro.slots.render and passes an array of arguments as the second argument when rendering:

    ---
    // /src/Component.astro
    ---
    
    {Astro.slots.render('default', ['foo'])}
  2. When using the component, you pass a function as its contents to be called with any arguments the component provides:

    ---
    // /src/pages/index.astro
    import Component from '../Component.astro';
    ---
    
    <Component>
      {(arg) => <strong>{arg}</strong>}
    </Component>
  3. It should render the markup returned by the function in the component’s slot:

    <!-- expected output -->
    <strong>foo</strong>

Actual behaviour

Most of the above works as expected, but the HTML markup appears to be escaped resulting in <strong>foo</strong> being output as plaintext in the browser:

&lt;strong&gt;foo&lt;/strong&gt;

Link to Minimal Reproducible Example

https://stackblitz.com/edit/github-kc4vjm?file=src/ComponentWhichIteratesAList.astro

Participation

  • I am willing to submit a pull request for this issue.
@matthewp matthewp added - P5: urgent Fix build-breaking bugs affecting most users, should be released ASAP (priority) - P4: important Violate documented behavior or significantly impacts performance (priority) and removed - P5: urgent Fix build-breaking bugs affecting most users, should be released ASAP (priority) labels Sep 20, 2022
@matthewp matthewp self-assigned this Sep 20, 2022
@matthewp
Copy link
Contributor

Since slots.render() returns a string you have to use set:html with it. However it's not working in this case because slots.render() returns a Promise and we're not awaiting that correctly. As a workaround you can do set:html={await Astro.slots.render('default', [arg])}, but I'll fix the bug so you don't have to do this.

@colinbate
Copy link
Contributor

Thanks for looking into this. If I attempt to use await in the component body (with set:html as above) it complains about using it outside of an async function.

@matthewp
Copy link
Contributor

@colinbate if you are in a loop like in this example make sure to mark the function as async. Fix is incoming to not require you to await it though.

@colinbate
Copy link
Contributor

@matthewp Thanks, that was what I was missing. It works with an HTML tag, but it doesn't work with <Fragment/>. It goes back to complaining about the await without async. Hopefully not an issue with the fix, but thought I'd mention it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
- P4: important Violate documented behavior or significantly impacts performance (priority)
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants