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

Can I Mithril for server-side components? #2851

Open
EverettMcKay opened this issue Jun 5, 2023 · 3 comments
Open

Can I Mithril for server-side components? #2851

EverettMcKay opened this issue Jun 5, 2023 · 3 comments
Labels
Type: Question For issues that are purely questions about Mithril, not necessarily bug reports or suggestions

Comments

@EverettMcKay
Copy link

I am using Mithril to build a website for what I hope to turn into a simple Saas. Currently I have a client component (in the format <Foo attr="some attr" />) whose code I would ultimately like to reside on a server and called by any client.

Can I do this with Mithril? Seems like all I need is to somehow serve a js script, which is what a Mithril ultimately boils down to.
Most of my experience has been client side, so apologies if this is a dumb question. My research so far hasn't panned out. Not knowing the right lingo doesn't help.

Possible alternatives I have found so far: Use mithril and Fusion.js, use Next.js, or perhaps just use Node+Express. Do any of these sound right?

But client side at least, Mithril has been perfect for my component and I love that it doesn't require (or even benefit from) all the complexity of React-based solutions.

@EverettMcKay EverettMcKay added the Type: Question For issues that are purely questions about Mithril, not necessarily bug reports or suggestions label Jun 5, 2023
@laoshaw
Copy link

laoshaw commented Aug 3, 2023

I am leaving react.js for mithril as all the SPA frameworks nowadays are focusing on SSR and server component. In fact there are many use cases for client-side only(do not care about SEO at all), I hope mithril stays the way it is, be the best lightweight CSR SPA forward.

@EverettMcKay
Copy link
Author

I wanted to follow up on this, as I need to make the decision soon (The decision: to use React or Next instead...gasp!)

To summarize my situation: my component code must live on the server. Pushing these components to clients is the product, so this is a hard requirement (I not doing some weird SEO thing) I don't own the client., but can only provide a code snippet to the client dev. Using Mithril would be ideal because it is so lightweight.

To nail down what I'm hoping for, the client code should look something like this:

<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>Mithril Server Component Test</title>
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <script src="https://unpkg.com/mithril/mithril.js"></script>
</head>
<body>
  <div>
    <div id="divID"></div>
  </div>
  <!-- client's SPA goes here -->
  <script>
    const loadComponent = (divID, apiKey, componentID, otherParams) => {
      const url = `myComponentServer?component=${componentID}&otherParams=${otherParams}`;
      const h = new Headers();
      h.append("Content-Type", "application/json");
      h.append(ApiKeyHeader, apiKey);
      const req = new Request(url, {
        method: "get",
        headers: h,
      });
      fetch(req)
        .then(async (res) => {
          if (res.status !== 200) {
            throw new Error(`Bad request: (${res.status}): ${res.statusText}`);
          }
          const body = await res.json();
          return body;
        })
        .then((content) => {
          const { component } = content;
          m.mount(document.getElementById(divID), component)
        })
        .catch((e) => {
          logEventConsole(`Error: loadSurvey: ${apiKey}, ${customerID}, ${surveyID}, ${userID}`, e);
        });
    };
    document.addEventListener('DOMContentLoaded', (event) => {
      loadComponent("divID", apiKey, componentID, otherParams);
    })
  </script>
</body>
</html>

Looks pretty normal so far. The trick is the server endpoint, which might look like:

const myComponent = () => ({
  tag: "myComponent",
  oninit: () => {},
  attrs: () => {},
  state: () => {},
  view: (v) => m("main", [
    m("h1", {class: "title"}, "My first app"),
    m("button", {onclick: () => {alert('clicked!')}}, "A button"),
    ]);
});

app.get("myComponentServer", validateKey, (req: Request, res: Response) => {
  const component = getSurvey(req, res, account);  // returns myComponent based on componentID
  if (!component) return;

  const comp = magicallyRenderedComponent(component); // returns component js
  const compJSON = JSON.stringify(comp);

  res.status(200).send(compJSON);
});

The server needs to return something the client's mithril can mount. Is this possible? From what I can tell, magicallyRenderedComponent doesn't exist.

(When I first started, I discovered mithril-node-render, but it appears to only return the html tagging and strips out all the js code so that won't do. )

@EverettMcKay
Copy link
Author

GIving up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Type: Question For issues that are purely questions about Mithril, not necessarily bug reports or suggestions
Projects
None yet
Development

No branches or pull requests

2 participants