Search code examples
javascriptweb-componentstenciljs

Is there a way to make a Stencil.js web component automatically insert itself into the DOM without user interaction?


I have a small stencil.js component, which I have published to npm, and created a CDN link for it.

The way it normally works is you copy the script with the cdn link, and then you insert the component by its tag name in your html:

<script type="module" src="https://cdn.jsdelivr.net/npm/[email protected]/dist/feedback-widget/feedback-widget.esm.js" defer></script>

<ifx-feedback-widget app-name="Some App Name"></ifx-feedback-widget>

What I want to do is to make it so that you don't have to write the tag name in your html, but the component to get invoked, i.e. insert itself into the DOM when the script is executed. The only way I know how to do that is by creating the component yourself, and then inserting it:

  <script>
    const myComponent = document.createElement('ifx-feedback-widget')
    document.body.appendChild(myComponent)
  </script>

but I don't want to have to do that. Is there a way for the component to insert itself into your DOM when the script is executed without any additional user action?


Solution

  • Yes this is possible, but technically it's not the component itself that can do it, it's the library.

    Your library can include "default" script code that is run when the main library script is loaded. You define that in your stencil.config.ts file e.g.:

        globalScript: 'src/global/index.ts',
    

    And it's contents would be something like:

    export default function() {
        document.addEventListener('DOMContentLoaded', () => {
            const myComponent = document.createElement('ifx-feedback-widget');
            document.body.appendChild(myComponent);
        });
    }
    

    You may also need to update src/index.ts:

    export * from './components';
    export * from './global';
    

    You might be able to just add the default function code to src/index.ts and point globalScript to that, but I haven't tried that myself whereas I know the above works.

    See https://stenciljs.com/docs/config#globalscript