question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Support dynamic content of app.html

See original GitHub issue

Describe the problem

While I imagine the current static approach for app.html is acceptable in ~99% of use cases, sometimes it would be useful to make its contents dynamic.

I have a multi-tenant application that loads a customer-provided skin at runtime and wraps my app in it. Hypothetically, let’s say the skin looks like this:

<html>
<head>
<title>APP!</title>
</head>
<body>
<p>some content before the application</p>
{{app}}
<p>some content after the application</p>
</body>
</html>

Achieving this isn’t particularly difficult.

//__layout.js
<script context="module">
  //load the skin async based on things like hostname
  //and other portions of the URL, then...
  return { props: { skin: skinHTML } };
</script>

const [before, after] = skin.split('{{app}}');
// ... some regex magic to strip out the html/head/body tags
{@html before}
<slot />
{@html after}

Indeed, this is exactly what I’m currently doing. But there’s a problem. If the skin wraps the app in a tag, Svelte(Kit?) starts to misunderstand the DOM and the app gets duplicated. Given a skin that contains this: <div>{{app}}</div>

The app behaves very oddly, and most of the time results in 2 copies of itself on the page. (To the best of my understanding, sometimes in dev hmr it will clean itself up to a single instance, but not always)

Here’s a video demonstrating why I want to do this, and how it affects the application: https://youtu.be/voYqm2Chu1U

If the contents of app.html were dynamic, it would be trivial for me to replace {{app}} with <div id="svelte"></div>.

Describe the proposed solution

I can see that everything is currently hard-coded to read app.html from the file system and use that value.

https://github.com/sveltejs/kit/blob/fb262e5d3ac551b369cf3f50d8a073975f8b0606/packages/kit/src/core/dev/index.js#L462-L465

It would be nice if there were some sort of hook or middleware that I could add that would be called instead that could return the HTML contents currently obtained from app.html. It would need to happen at runtime (server-side) so that I can parse the URL to get the correct skin for the current hostname.

Alternatives considered

The only other thing I can think of is to use Vanilla Svelte and express/etc to set the page contents to the skin at runtime. I’d hate to give up the routing/etc benefits of SvelteKit, though.

I haven’t been able to think of any other alternatives, but I’m open to any current/proposed solution that lets me build the features I need in my app. It doesn’t have to be the solution I proposed.

Importance

would make my life easier

Additional Information

No response

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:2
  • Comments:10 (5 by maintainers)

github_iconTop GitHub Comments

2reactions
rmunncommented, Nov 11, 2021

For what it’s worth, the system where customers provide the skin HTML to us is not a node server, it’s an entirely different platform (java-based, which is why I said I might be able to use jSoup)…

I take it the customers need to be able to update the skin “live”, i.e. they expect to be able to update the skins and have their updates take effect immediately. If they would find it acceptable to submit their proposed skins to you and wait for you to update their sites later, then you could insert a manual checking step where you could see what they’ve wrapped {{app}} in, and possibly update the regex accordingly. But I’m guessing you need them to be able to update “live”, and therefore you can’t know ahead of time how {{app}} will be wrapped. Is that right?

Why don’t just create some specific element, and use querySelector? You can do it on server-side too with jsdom or any other parser.

I don’t follow exactly.

I think @Mlocik97 meant that instead of asking your customers to put {{app}} in their markup, ask them to put in a specific element (or, I would add, an element with a specific ID). I.e. ask them to put <div id="app"></div> in their markup. Then after you retrieve the skin HTML, you can use existing HTML-parsing tools to find the div you need to replace, and remove the html/head/body stuff, etc. Which is going to be more reliable than regexes: if the customers give you malformed HTML skins, you can have the Java platform return an error saying “Must be valid HTML, here’s the part that was invalid”.

Am I barking up the wrong tree?

I’m afraid I don’t know the guts of the adapter system well enough to answer this, sorry. You’re quite right that the Svelte discord is the right place to ask for help, so that these issue comments can be kept focused on your specific feature request (dynamically selecting the template HTML instead of serving up a static file). Thank you for keeping a good separation between feature requests and associated discussion (which do belong here), and “how do I do this thing?” requests, which belong either in the discord channel or in the GitHub Discussions feature. (I believe the project is planning to move to Discussions, but at the moment the discord channel is more active and you’ll likely get faster responses there).

2reactions
rmunncommented, Nov 10, 2021

Part of what’s going on with the <div>{{app}}</div> case is that you’re using @html to render the “before” and “after” portions, and if {{app}} is wrapped in a div then that will cause @html to be passed HTML that isn’t valid standalone HTML. (That’s even the example used in https://svelte.dev/docs#html as an illustration of what won’t work). I think if you fix your regex to detect a wrapped {{app}} and remove that wrapper div (assuming it had nothing else inside it), then you should be able to make progress.

Because of that, I’m not yet persuaded that changing Svelte-Kit to load the app.html dynamically is the only way to solve your use case, though I can see where it would have advantages for you (it would certainly be simpler than the regex approach you’re currently using). But as it’s not necessary for most use cases, I suspect the only way you’ll see this feature request implemented is to “scratch your own itch” by submitting a PR.

Alternately, if you don’t want to wait for this feature request to be implemented, one thing you might be able to do for yourself, without needing to submit a PR to the Svelte-Kit project, is to write your own adapter to take the built app and adapt it to load the template dynamically. You’d want to look at these lines of code to see what it’s producing and what you’d want to change.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Mobile Dynamic Content Campaigns
Dynamic Content campaigns allow you to replace static components and turn them into dynamic experiences by controlling them directly from the Dynamic Yield ......
Read more >
Designing mobile APIs – dynamic content - Carbon Five Blog
One possible solution would have been to render a html form in a web view. Web views often offer a convenient way to...
Read more >
Deliver Your App's Dynamic Content Using Amazon CloudFront
Many websites and web applications serve a combination of static content—HTML, CSS, JPG, or other files that all end viewers can see—and ...
Read more >
Add dynamic content to an existing HTML5 Web App for Android
I have created a mobile web application using HTML5,CSS3 and Javascript/Jquery. I've used the PhoneGap Build to get it's apk. Once people ...
Read more >
HTML template based on dynamic data in PowerApps
Using HTML templates is a great way to format and display data within in PowerApps applications, to generate reports and to send emails ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found