Publish date: 2022/02/28 Update date: 2023/03/03

Make Svelte better

Logic blocks syntax

The current syntax used for logic blocks looks weird and hard to write and remember, especially for beginners.

{#if}
{:else if}
{:else}
{/if}

{#each}
{/each}

{#await}
{:then}
{/await}

{#key}
{/key}

{@html}
{@const}
{@debug}

Let’s use a simple and clean syntax like this example:

{@if}
{@else if}
{@else}
{@endif}

{@each}
{@endeach}

{@await}
{@then}
{@endawait}

{@key}
{@endkey}

{@html}
{@const}
{@debug}

$alias

We use the $ symbol when accessing a store value, and I think it will be confusing for beginners if we also use it in our alias names. Developers may confuse about differentiating an alias from a store name. You can name your aliases however you like, but the svelte maintainers prefer the $ prefix, so that will be what most developers use.

<script>
	// Hmm, let's create a variable for our path:
	const components = readable("/src/lib/components")

	// Now, let's use it to import our component:
	import MyComponent from "$components/MyComponent.svelte"
</script>

Let’s use the @ symbol instead:

<script>
	import MyComponent from "@components/MyComponent.svelte"
</script>

This will indeed make Brittney so happy😄.


class prop

Let’s say you want to create a prop to add custom classes to your component. Let’s see how we can do that.

MyComponent.svelte:

<script>
	export let class
</script>

<div {class} />

App.svelte:

<script>
	import MyComponent from "./MyComponent.svelte"
</script>

<MyComponent class="my-class" />

<style>
	.my-class {
		display: block;
	}
</style>

The example above is a simple and clean way to add custom classes and styles to your component from a parent component. The problem is, that doesn’t work! To make it work, you need to change some stuff in MyComponent.svelte:

<script>
	export let className
	export { className as class }
</script>

<div class={className} />

Now you can add your custom classes. But don’t get happy yet, because there is a catch. Your custom classes will only work if they are global, like in the old days when we had one big CSS file and were using it for everything. The problem is, Svelte doesn’t recognize the prop as a class attribute. As a result, it thinks the .my-class styles are not being used, so it removes them from the output. Fix it like this:

<div class="my-wrapper">
	<MyComponent class="my-class" />
</div>

<style>
	.my-wrapper :global(.my-class) {
		display: block;
	}
</style>

Using the :global feature makes your styles global to your entire app. We add the my-wrapper element to the scope that styles back into your component.


Comments

None of these examples work. Because the Svelte maintainers think we should carry around these existing problems in HTML, CSS, and JavaScript and that they don’t worth solving. You can’t also wrap an HTML attribute or a component prop inside a comment tag.

<!-- <div>
	<!-- <div></div> -->
</div> -->
<div
	<!-- class="" -->
></div>
<MyComponent
	<!-- myProp="" -->
></MyComponent>
/* div {
	/* display: block; */
} */
/* function doAThing() {
	/* console.log() */
} */

CSS scope

svelte#6972


A11Y

We need a feature to disable all A11Y warnings together, on the frontend and in the terminal. We may also need to disable them individually, so if there was an incorrect warning, we easily disable it.


Layouts


Dynamic classes

There is no clean syntax to dynamically add classes.

Syntax 1

<div class:bg-brand={condition} />
  • ❌ This isn’t a standard syntax because the classes should come after the equal sign.
  • ❌ You can’t use multiple classes, and because of that, you need to introduce a new syntax to your codebase.

Syntax 2

<div class={condition ? "bg-brand rotate-45" : ""} />
<div class="{condition ? 'bg-brand rotate-45' : ''} text-white" />
  • ✅ You can use multiple classes.
  • ❌ Boilerplate.

Syntax 3

<div class="{condition && 'bg-brand rotate-45'} text-white" />
  • ✅ You can use multiple classes.
  • ✅ Clean and readable.
  • ❌ You may get classes like false, null, and undefined as a result of a Falsy value.

What is the solution?

Use Syntax 3 and ignore adding classe like false, null and undefined. Also, deprecate Syntax 1 in Svelte version 4, because it’s not gonna be useful anymore.


Port is already in use

Automatically change the port number if the current one is already in use.


Dynamic HTML tags

This feature is now available 👏.

<script>
	let tag = 'div'
</script>

<svelte:element this={tag}>
	...
</svelte:element>

Change the this prop name to tag, because what if we also want to bind the element to a variable? Example:

<script>
	let tag = 'div'
	let element
</script>

<svelte:element
	this={tag}
	bind:this={element}
>
	...
</svelte:element>

It works, but it looks like we accidentally added the prop twice!


Docs

Documentation content and the design needs a rewrite and a redesign. There is a lot of content missing in the docs It’s the year 2022 and we don’t have a freaking Dark Mode! A proper way of accessing and searching content. Algolia sucks because it’s not accessible it some countries like Iran, so need to use a VPN to be able to use it!


Better error handling

It’s absolutely disgusting how Svelte handles errors! Basically, you don’t know what the hell is going on.


Internationalization

You can learn about how PHP and Wordpress do i18n from here:

Using JSON .json files for i18n is a huge big mistake. We should use PO (.pot, .po, .mo) files instead because they are a known standard for years for millions of developers and translators, and software when creating translation files. It’s not just the PHP ecosystem that uses this convention. Svelte can take the same solution and implement it. This will highly benefit everyone. Using JSON files is hard, unmaintainable, and tidies. You can easily use tools like PoEdit for translation with the power of the community’s previous translations, AI-like features, and by getting help from Google Translate. We also need to use syntaxes like __() for wrapping the translatable strings because it is a known standard.

Return to top