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

Component discovery #2594

Closed
dreitzner opened this issue Oct 13, 2021 · 5 comments
Closed

Component discovery #2594

dreitzner opened this issue Oct 13, 2021 · 5 comments

Comments

@dreitzner
Copy link
Contributor

Describe the problem

Let's assume there is a CMS that feeds into a svelte-kit website.

A content editor in the CMS should have the ability to use different modules inside the CMS which would translate into Svelte components, like Headline, Image, Paragraph, etc.

Currently there is no way to generically Render components driven by an outside source (to my knowledge).

it would be great to be able to use something like this:

{#each cmsEntity as {id, name, data}(id)}
  <svelte:component {name} {data} />
{/each}

Describe the proposed solution

Something similar to Nuxt.js' component discovery.

https://nuxtjs.org/docs/features/component-discovery/

Folder structure:
/lib/components
|- Header.svelte
|- /base
  |- Button.svelte
// use it in index.svelte route without import
<Header />
<BaseButton>Click Me</BaseButton>

The base component directory could also be something that is exposed through the config, but I think having it only one way would be preferable.

Alternatives considered

No response

Importance

nice to have

Additional Information

No response

@dominikg
Copy link
Member

Sounds like mdsvex custom components may help you https://mdsvex.com/docs#custom-components

@Prinzhorn
Copy link

Prinzhorn commented Oct 13, 2021

Something similar to Nuxt.js' component discovery.

I think the difference here is that you want that at runtime. What you've linked happens at compile time

The common solution to your problem is to keep a Map<String, Component> (or similar) in a js file and then lookup the component by it's name/key/id at runtime. This also has the benefit that you need to be explicit about what components are "blessed" and can be used by your CMS. You don't want someone to inject arbitrary components (with arbitrary props), which can lead to XSS or other isses.

{#each cmsEntity as {id, name, data}(id)}
  <!-- TODO: handle lookup errors (unknown name), bless/validate certain props -->
  <svelte:component this={cmsComponents.get(name)} {data} />
{/each}

Edit: of course this could still be a valid feature request to generate such a map (maybe for certain folders) automatically. But I don't see how this needs to be limited to SvelteKit. For reference here's an issue I've created in the past when I did something similar in Svelte sveltejs/svelte#6537

@yuanchuan
Copy link

yuanchuan commented Oct 16, 2021

I've used this plugin I wrote and it works pretty well. I post it here in case of it'll meet your need.

https://github.com/yuanchuan/vite-plugin-autoimport

@dreitzner
Copy link
Contributor Author

@yuanchuan that is really awesome 🥳

I'll close this issue and will use that if I ever need it.

Thank you for your awesome contribution.... Maybe we can add it to the recipes on svelte society :)

@dominikg
Copy link
Member

dominikg commented Oct 16, 2021

Note that using auto-import and thus not adding explicit imports to a .svelte file prevents static analysis like vite optimizer from scanning them correctly.

I don't recommend it and suggest to use IDEs auto-generating imports for you as you type up your template.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants