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

How to handle javascript templates of hydrated components? #28

Open
daKmoR opened this issue Nov 5, 2022 · 1 comment
Open

How to handle javascript templates of hydrated components? #28

daKmoR opened this issue Nov 5, 2022 · 1 comment

Comments

@daKmoR
Copy link

daKmoR commented Nov 5, 2022

Question

How would you recommend handling javascript templates of hydrated components?

Description

Let's look at a concrete simplified example
Note: this example uses Declarative Shadow Dom which is currently only supported in chromium browsers

👉 index.html

<h1 data-rosey="intro">Let's start</h1>

<say-hi>
  <template shadowroot="open">
    <p data-rosey="welcome">welcome</p>
  </template>
</say-hi>

<button>hydrate</button>

this html can be translated by rosey and could for example look like this in German

👉 index.html

<h1 data-rosey="intro">Lass uns anfangen</h1>

<say-hi>
  <template shadowroot="open">
    <p data-rosey="welcome">Willkommen</p>
  </template>
</say-hi>

<button>hydrate</button>

but now let's say we need to hydrate this say-hi component as it for example tracks how often users hover over the welcome message...

e.g. we need to hydrate the component and it comes with the "template" (again) but that template is not touched by rosey right?

It could look something like this

class SayHi extends HTMLElement {
  connectedCallback() {
    this.shadowRoot.innerHTML = `<p data-rosey="welcome">welcome</p>`;
    // For example: tracking how many people hover the welcome text 
    // this.addEventListener('hover', () => // api call for tracking);
  }
}
document.querySelector('button').addEventListener('click', () => {   
  customElements.define('say-hi', SayHi);
});

You can see it live in action in this codepen
https://codepen.io/daKmoR/pen/abKmoxG?editors=1010

so as soon as we hit this hydrate button we will "lose" the translation and the text will become

Lass uns anfangen
welcome

Ideas

Puh yeah... as html can be created in all kind of forms within a javascript (web) component it's probably hard/impossible to correctly extract/modify...

Also adjusting and creating duplicate JS is probably also hard "after" it has already been optimized by a bundler 🤔

I mean there are project for lit web components which come with some rules/limitation e.g. only declarative html, ...

https://lit.dev/docs/localization/overview/

Maybe it could be combined somehow... 🤔

What are your thoughts on this?

@bglw
Copy link
Contributor

bglw commented Nov 15, 2022

👋 Hello @daKmoR!

This is an area we're keen to start looking at, but we haven't done any particular scoping on it yet — lots of questions as to how it might best be done! It's a pertinent question for many new not-quite-static stacks that we would like to support, e.g. Next, SvelteKit, Astro.

Most likely the best path would be for Rosey to provide some JS API to the site that allows it to register/retrieve translations. Registering a translation is the harder problem, since Rosey currently performs what is essentially a static analysis of a website to extract the data-rosey tags. To integrate into this flow, Rosey would need to perform a static analysis of the JS to find all translation strings.

The direction I've been looking to investigate might look like the following:

import roseyTranslate from "rosey";

...

this.shadowRoot.innerHTML = `<p>${roseyTranslate({ key: "welcome", original: "welcome" })}</p>`;

...

Where the rosey CLI can discover these function calls and integrate those keys into its existing flow, such that the final output site can call the roseyTranslate function and get the welcome key as expected.

Still lots of scoping to do here, the bundler minification process for example throws a large spanner in the works for making this JS discoverable, which might require a different approach altogether.

So nothing to report yet, but open to further thoughts!

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

2 participants