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

Multiple apps on single page #1115

Open
collinglass opened this issue Apr 28, 2024 · 5 comments
Open

Multiple apps on single page #1115

collinglass opened this issue Apr 28, 2024 · 5 comments

Comments

@collinglass
Copy link

Hey, I’m looking to use this to rewrite my current widget. Our customers add our JavaScript lib to the head tag. And then we inject html CTAs inside DOM elements where they put our CSS classes. Usually 3-4 CTAs per page. Clicking any of these CTAs opens up a modal with an iframe.

what is the best way to accomplish this with hyperapp?

@zaceno
Copy link
Contributor

zaceno commented Jul 21, 2024

What is a CTA, if I may ask?

@zaceno
Copy link
Contributor

zaceno commented Jul 21, 2024

Anyway, this doesn’t sound much like the kind of use-case hyperapp is best for. Unless you’re talking about the iframe content - but each iframe will be its own isolated page so using hyperapp in there shouldn’t be a problem

@skanne
Copy link
Contributor

skanne commented Jul 22, 2024

Isn't CTA spelled out "call-to-action", in other words, a button?

@collinglass
Copy link
Author

Yes. In general, something that we want users to click on or do. Can be just a button, in our case, it can also be an ad-like banner or inline block

@skanne
Copy link
Contributor

skanne commented Jul 22, 2024

Regarding "Multiple apps on single page": It's perfectly valid/feasible to have multiple Hyperapp apps running at the same time on the same page. I personally like to have them run inside dedicated web components. This way, such mini-apps can even be nested. Think <outer-app><inner-app></inner-app></outer-app>.

I've outlined it for you here:

<script type="module">
  import { h, app } from "https://unpkg.com/hyperapp";

  const styleSheets = new CSSStyleSheet();
  styleSheets.replaceSync(`
    :host {
      /* call-to-action styles */
    }
    button {
      /* button styles */
    }
  `);

  class CallToAction extends HTMLElement {
    #dispatch;

    constructor() {
      const shadowRoot = super().attachShadow({ mode: "open" });
      shadowRoot.adoptedStyleSheets = [styleSheets];
      shadowRoot.innerHTML = "<button></button>";
    }

    connectedCallback() {
      this.#dispatch = app({
        init: {
          /* component state */
        },
        view: (state) =>
          h(
            "button",
            {
              /* button attributes */
            },
            h("slot", {})
          ),
        node: this.shadowRoot.firstChild,
      });
    }

    disconnectedCallback() {
      this.#dispatch((state) => undefined);
    }
  }

  customElements.define("call-to-action", CallToAction);
</script>

<call-to-action>CTA</call-to-action>

You can either import Hyperapp from a CDN, like import { h, text, app, memo } from "https://unpkg.com/hyperapp"; and do so in each of your app modules, or you do it once and put Hyperapp into the global scope (yes, you'd soil the window somewhat) via import * as hyperapp from "https://unpkg.com/hyperapp"; window.hyperapp = hyperapp; and then destructure from the global hyperapp object: const { h, text, app, memo } = window.hyperapp;.

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

3 participants