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

<svelte:script>, <svelte:style> and <svelte:template> #12678

Closed
jackvanderbilt-visma opened this issue Jul 31, 2024 · 11 comments
Closed

<svelte:script>, <svelte:style> and <svelte:template> #12678

jackvanderbilt-visma opened this issue Jul 31, 2024 · 11 comments

Comments

@jackvanderbilt-visma
Copy link

jackvanderbilt-visma commented Jul 31, 2024

Describe the problem

I find the current implementation of the root <style> and <script> tags in Svelte frustrating because they aren't actual <style> and <script> tags; they have special syntax and transformations going on, and never get shipped to the browser dom, causing confusions to the less informed about what works, what does not work and what to expect to be inserted into the browser dom.

Also, when adding vanilla <style> and <script> tags, they must be placed inside a wrapper element, which feels cumbersome and just pollutes the code (and final dom).

Additionally, new users to Svelte who've come from other frameworks often find the absence of a <template>-like tag confusing when structuring their markup. This lack of clear separation between configuration/Svelte logic and DOM markup can lead to misunderstandings and a steeper learning curve.

Moreover, the ability to place special <svelte: elements such as <svelte:head> and <svelte:window> anywhere within a component's markup often results in what I consider to be unattractive and disorganized code.

In larger codebases, all of the above-mentioned stuff; this flexibility, leads to what I consider unnecessarily messy and unreadable code, and has made maintenance and collaboration more difficult.

Describe the proposed solution

I propose that Svelte should require the top-level <script> tag to be written as <svelte:script> to clearly indicate it is a script tag processed by Svelte. Similarly, the <style> tag should be renamed to <svelte:style>, especially since it supports the special :global() syntax, which is not available in vanilla CSS nor in other style tags within the same Svelte component.

Additionally, I suggest introducing a <svelte:template> tag. This optional tag would, when included in a component, mandate that all <svelte: elements be placed outside of it (unless configured otherwise in the Svelte config, where <svelte:element> is enabled by default). While it doesn't offer new functionality (attributes, binds, or anything else), it enforces different rules and provides a clear separation between configuration/Svelte logic and DOM markup. Again, it is an opt-in element.

Example Current Structure:

<script>
	let hello = 'world'
</script>

<svelte:head>
	<title>Test</title>
</svelte:head>

<div>
	{hello}
	<script>// must be placed here due to single script in root rule</script>
	<style>/* must be placed here due to single style in root rule */</style>
</div>

<style>
	:global(div) {
		background-color: red;
	}
</style>

Proposed Structure:

<svelte:script>
	let hello = 'world'
</svelte:script>

<svelte:head>
	<title>Test</title>
</svelte:head>

<svelte:template>
	<div>
		{hello}
	</div>
	<script>// no problem </script>
	<script>// have as many as you want </script>
	<script>// no problem </script>
	<style>/* no problem */</style>
	<style>/* no problem */</style>
	<style>/* no problem */</style>
</svelte:template>

<svelte:style>
	:global(div) {
		background-color: red;
	}
</svelte:style>

This proposed structure would provide a clearer and more consistent approach to defining Svelte components.


Additional Benefits:

  1. Prevent Future Spec-Collision Concerns: By not re-using the vanilla <script> and <style> tags, we can avoid potential future specification collisions. For instance, this concern was raised in Rich Harris's recent issue discussion on GitHub: Svelte Issue #12637.

  2. Alignment with Deprecation Trends: Considering the deprecation of <svelte:component> as discussed in Svelte Issue #12668, the proposed optional <svelte:template> element would generally be non-intrusive. The only scenario where it might be slightly inconvenient is when using <svelte:element>, which is relatively rare and mostly applicable to developers creating dynamic form components or web page builders.

Importance

nice to have

@7nik
Copy link

7nik commented Jul 31, 2024

You propose to use <template> and even <svelte:template>, plus <svelte:script> and <svelte:style>, but Vue doesn't use prefixed tags in SFC: just ordinary <template>, <script>, and <style> and nobody gets confused, as well as in Svelte. So why should we do it? It's basic knowledge in Svelte that <script> and <style> are special, and putting your own ones usually means you are doing something wrong.

the ability to place special <svelte: elements such as <svelte:head> and <svelte:window> anywhere within a component's markup

These two and <svelte:body> can be located only at the root, and basically your proposal changes nothing here.

new users to Svelte who've come from other frameworks often find the absence of a <template>-like tag confusing when structuring their markup

New to Svelte users should learn the official tutorial (if they came from another framework(s), it especially won't take much time), and everything become clear.

@Rich-Harris
Copy link
Member

We're not going to do this. It would be a massively disruptive change...

<!-- github knows how to syntax highlight this, as does everything else -->
<script>
  let x = 1;
</script>

<style>
  .banana {
    color: yellow
  }
</style>
<!-- ??? -->
<svelte:script>
  let x = 1;
</svelte:script>

<svelte:style>
  .banana {
    color: yellow
  }
</svelte:style>

...that 99.9% of people would consider a step backwards.

@Rich-Harris Rich-Harris closed this as not planned Won't fix, can't repro, duplicate, stale Jul 31, 2024
@UltraCakeBakery
Copy link

We're not going to do this. It would be a massively disruptive change...

<!-- github knows how to syntax highlight this, as does everything else -->
<script>
  let x = 1;
</script>

<style>
  .banana {
    color: yellow
  }
</style>
<!-- ??? -->
<svelte:script>
  let x = 1;
</svelte:script>

<svelte:style>
  .banana {
    color: yellow
  }
</svelte:style>

...that 99.9% of people would consider a step backwards.

github knows how to syntax highlight this, as does everything else

Here is how VueJS added syntax highlighting to GitHub. It doesn't look all that complicated; I'm sure someone can make it work for the current svelte syntax, as well as the one I suggested too.

It would be a massively disruptive change...

I agree for now, but once Runes has landed, and you guys are looking to further improve svelte, I think you will want to start reconsidering all the possibilities this feature request opens up.

@Rich-Harris
Copy link
Member

It doesn't look all that complicated

Great, now make it work for Stack Overflow, and Discord (where you can use an html fence), and CodeMirror, every single IDE, and lord knows what else.

I think you will want to start reconsidering all the possibilities this feature request opens up

It doesn't open up any possibilities, it's just change for the sake of unnecessary change

Alignment with Deprecation Trends

Adding new <svelte:foo> elements is not in alignment with the trend of deprecating <svelte:component> and <svelte:fragment>

@UltraCakeBakery
Copy link

UltraCakeBakery commented Jul 31, 2024

new users to Svelte who've come from other frameworks often find the absence of a <template>-like tag confusing when structuring their markup

New to Svelte users should learn the official tutorial (if they came from another framework(s), it especially won't take much time), and everything become clear.

You propose to use <template> and even <svelte:template>, plus <svelte:script> and <svelte:style>, but Vue doesn't use prefixed tags in SFC: just ordinary <template>, <script>, and <style>

It is kind of scary that people do not get confused considering that we are building websites; people should get confused, and Vue shouldn't use those tags in my opinion. Just because something is populair or common, doesn't mean it's the right or best thing; svelte could (should) take the opportunity here to get ahead of the hive-mind/"competition" (for lack of a better word).

and nobody gets confused, as well as in Svelte. So why should we do it? It's basic knowledge in Svelte that <script> and <style> are special,

It used to be basic knowledge that export let prop is a prop, and $: is a "computed property", but it is being phased out for good reasons too.

putting your own ones usually means you are doing something wrong.

'usually' yeah; but if you are building progressively enhanced websites using svelte kit, it happens more often than you think. But I agree on this one, though being able to just place google analytics scriptags in my layout.svelte without being scared of it potentially not working would be great.

These two and <svelte:body> can be located only at the root, and basically your proposal changes nothing here.

Apologies: I genuinely didn't know that and assumed due to the other rules about root <script> and <style>; though I do find it ironic that I got confused in relation to my original request haha.

New to Svelte users should learn the official tutorial (if they came from another framework(s), it especially won't take much time), and everything become clear.

I could literally answer the exact same thing to anyone complaining about my proposed changes once they are implemented, but I wouldn't because they are based on lots of assumptions.

@7nik
Copy link

7nik commented Jul 31, 2024

Can you provide an example of a framework that uses prefixes for script, style and template tags? I checked Angular SFC, and it doesn't have them either. Most of the other frameworks are JSX-based and don't have SFC at all.

It is kind of scary that people do not get confused considering that we are building websites; people should get confused, and Vue shouldn't use those tags in my opinion.

Technically, these script and style tags are unrelated to HTML ones and have their own set of attributes. But we write them in .svelte, .vue, and .analog files, but not .html, and their syntax is not HTML but a similar/derived one. And it's one of the first things you learn in a framework SFC syntax.

It used to be basic knowledge that export let prop is a prop, and $: is a "computed property", but it is being phased out for good reasons too.

Yep, they have a whole bunch of flaws, but the tags don't - you're likely the first to complain about them.

just place google analytics scriptags

Option 1: put them inside the app.html template
Option 2: use a package, maybe ga-gtag fits here
Option 3: just wrap with <svelte:head>
Enough solutions and articles about it.

@jackvanderbilt-visma
Copy link
Author

Great, now make it work for Stack Overflow, and Discord (where you can use an html fence), and CodeMirror, every single IDE

The VueJS community is thriving on Stack Overflow without slightly nicer syntax highlighting. It wouldn’t be surprising if Stack Overflow migrated to using linguist or something similar to enhance user experience, especially given the impact of AI bots.

Regarding Discord, it's not ideal for help requests or sharing svelte code anyways; using the GitHub discussions tab is better. GitHub discussions allow questions and shared Svelte code to be searchable via search engines like Google. Since Discord is public but behind an authentication wall, it’s not indexed or findable. If this weren’t the case, you wouldn’t need to constantly advertise the strength of your community; it would be evident. People being promoted to share their code through more suited platforms is something that would only benefit Svelte's ecosystem and the people in it in the long run.

Most popular IDEs have Svelte extensions that take little to no effort to install. Anyone using Svelte and writing Svelte code long-term uses these extensions. These are the users for whom you're making changes to Svelte.

and lord knows what else.

One told me once that “If the Lord doesn’t inform you about it, it’s none of your concern.”. I think that applies here very nicely.

It doesn't open up any possibilities, it's just change for the sake of unnecessary change

I disagree but respect your perspective. I'm passing you a "change my mind for free" card in case it benefits you in the future.

Adding new <svelte:foo> elements is not in alignment with the trend of deprecating <svelte:component> and <svelte:fragment>

If I were discussing the trend of removing all svelte:* elements, I’d agree. However, I’m specifically referring to the trend of removing svelte:* elements that are not often positioned at the component's root. This I could've clarified better.

@jackvanderbilt-visma
Copy link
Author

jackvanderbilt-visma commented Aug 1, 2024

Can you provide an example of a framework that uses prefixes for script, style and template tags? I checked Angular SFC, and it doesn't have them either. Most of the other frameworks are JSX-based and don't have SFC at all.

My point is that all frameworks should prefix (or rename) their elements. Reusing existing HTML elements is, in my opinion an absolute sin, or at least a mistake. The <script> tag should remain vanilla, as should <style>. If they contain anything other than JavaScript or CSS, they should use the type attribute, which Svelte does not enforce.

Technically, these script and style tags are unrelated to HTML ones and have their own set of attributes. But we write them in .svelte, .vue, and .analog files, but not .html, and their syntax is not HTML but a similar/derived one. And it's one of the first things you learn in a framework SFC syntax.

How am I supposed to know whether this is a badly formed HTML file or a Svelte component?

<script>
console.log(1);
</script>

<div>hello world</div>

<style>
div { 
color: red;
}
</style>

You could argue that it doesn’t matter, but imagine someone asking, "How do I change the contents of the div?" without mentioning it is a Svelte component on Stack Overflow. They might receive answers using DOM APIs manually, like querySelector and .innerHTML assignments.

Due to the lack of clarification by the language itself (e.g., the lack of Svelte prefixes), I am now forced to specify that I am using Svelte whenever I share my code. This is something people often miss when quickly reading / scanning text, which explains why they (new users to svelte) attempt to use and fallback to using regular JavaScript inside Svelte instead of doing things the Svelte way.

The language itself should make it clear that you are not writing generic JavaScript; you are writing "Svelte Script". The same goes for <style>—you are not writing generic CSS but "Cascading Svelte Sheets".

<svelte:script>
console.log(1);
</svelte:script>

<div>hello world</div>

<svelte:style>
div { 
color: red;
}
</svelte:style>

Yep, they have a whole bunch of flaws, but the tags don't - you're likely the first to complain about them.

The tags have flaws, as I mentioned above. And I am not the first to complain about them; you can tell by the speed at which Rich was able to close this issue and mark it as not planned. He has thought about it before.

Option 1: put them inside the app.html template

Last I checked, the SvelteKit team really wants to make app.html unnecessary. My feature request could further open that door, potentially entirely.

Option 2: use a package, maybe [ga-gtag].

Installing another package shouldn’t be the answer. Svelte shouldn’t make it harder for me to do basic web tasks like adding a script tag.

@7nik
Copy link

7nik commented Aug 1, 2024

How am I supposed to know whether this is a badly formed HTML file or a Svelte component?

The same as complaining that from

var x  = 42

it's not clear what the language is, so each language should use its own unique way of doing every single thing.
It is the same as googling a problem without specifying the language.
It is the same as asking a question without mentioning the related environment (OS, IDE, packages, libs, and other nuances - not all, but only related ones).
It is the same as providing JS code with runes or $stores without mentioning it's Svelte and then wondering why people not familiar with Svelte get puzzled.
People, indeed, get confused or misled when you provide no context or the context is incomplete. But it's not their problem that they cannot read minds and don't know every single language/framework/library/etc.

Last I checked, the SvelteKit team really wants to make app.html unnecessary.

Where have you seen this? Link, please.

trend of deprecating <svelte:component> and <svelte:fragment>

It's not even a trend, just a coincidence. These elements became redundant as a result of the framework's evolution, and thus, the API surface can be reduced.
If, e.g., the framework evolved in throwing away all the inline component options, then <svelte:options> likely would be deprecated.

@jackvanderbilt-visma
Copy link
Author

jackvanderbilt-visma commented Aug 1, 2024

How am I supposed to know whether this is a badly formed HTML file or a Svelte component?

The same as complaining that from

var x  = 42

it's not clear what the language is, so each language should use its own unique way of doing every single thing.

That is obviously a dumb take for one to have, and also not what I was saying at all.

My issue lies in the claim that Svelte is still a superset of HTML, when it also extends CSS, JavaScript, and by extension their supersets (scss, typescript through processors). Due to this: it no longer makes sense to me for the root <script> and <style> tags not to renamed (or as I suggested, to be prefixed with svelte:), considering their contents differ from their vanilla HTML counterparts.

I would even say that these tags should have been renamed in Svelte 3, where the languages differed more from vanilla than they do now.

People, indeed, get confused or misled when you provide no context or the context is incomplete. But it's not their problem that they cannot read minds and don't know every single language/framework/library/etc.

It’s not their problem indeed; so if Svelte could eliminate the need for these helpful individuals to ask questions to obtain more context by clearly indicating that something other than vanilla HTML/CSS/JavaScript is being used in the snippet of code, it would be a positive change. Making the language more intuitive to programmers would benefit everyone.

Last I checked, the SvelteKit team really wants to make app.html unnecessary.

Where have you seen this? Link, please.

This is based on general discussions over the last two years. The app.html file exists due to technical limitations, like <svelte:html> not being a thing and therefore not allowing the lang="" attribute to be set dynamically using svelte binds, or <svelte:body> not accepting the class attribute to be set. I and others don’t see the point of app.html and transform functions in server hooks anymore, but that’s not the issue here, so I’ll leave it at that.

trend of deprecating <svelte:component> and <svelte:fragment>

It's not even a trend, just a coincidence. These elements became redundant as a result of the framework's evolution, and thus, the API surface can be reduced. If, e.g., the framework evolved in throwing away all the inline component options, then <svelte:options> likely would be deprecated.

It would be a positive trend if it were to be imo.

@Rich-Harris
Copy link
Member

This is a ridiculous and pointless thread, so I'm going to save you from wasting any more of your time by locking it.

@sveltejs sveltejs locked as off-topic and limited conversation to collaborators Aug 1, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants