Updated: 5 months ago Published: 1 year ago

Make Svelte better

Syntax of logic blocks

The current syntax used for logic blocks can be challenging for beginners to write and remember. Therefore, it’s crucial to propose a simple and clean syntax that could make it easier to work with. Proposed syntax:

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

{@each}
{@endeach}

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

{@key}
{@endkey}

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

Creating a class prop

Have you ever tried to create a class prop to add custom classes to your component, only to discover that it’s not that straightforward? If so, you’re not alone. Let’s take a closer look at how to create a class prop in Svelte and the unexpected hurdles you may face along the way.

To start, let’s create a component and add the class prop to it:

MyComponent.svelte:

<script>
	export let class
</script>

<div {class} />

App.svelte:

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

<MyComponent class="my-class" />

<style></style>

At first glance, this seems like a simple and clean way to add custom classes and styles to your component from a parent component. However, there’s a problem - it won’t work! To make it work, you need to make some changes to MyComponent.svelte.

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

<div class={className} />

By exporting className and then aliasing it as class, you can now add your custom classes. But, as you may have guessed, there’s another catch. Your custom classes will only work if they are global. Svelte doesn’t recognize the prop as a class attribute, and as a result, it thinks the .my-class styles are not being used, so it removes them from the output.

So how can you fix this issue? One solution is to use the :global modifier to make your styles global across your entire app.

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

<style></style>

By wrapping the component inside an element and adjusting the CSS selector, we make sure that styles don’t leak out from the parent component.

Comments

None of these examples work because the Svelte maintainers believe these issues don’t worth solving and we should just deal with them! As you can see, you can’t comment code in a bunch of scenarios.

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

CSS scope

A11Y

We need the option to disable all A11Y warnings altogether, from all the places (Terminal, Browser console, Svelte vsCode extension).

By making it easier to manage accessibility warnings, we can ensure that developers are still able to create accessible web applications while reducing the burden of dealing with warnings that may not be relevant to their specific use case.

Layouts

Dynamic classes

Managing dynamic classes in Svelte can be improved for better code readability and flexibility.

The class directive

<div class:bg-brand={condition} />
  • ❌ Can only add one class at a time.
  • ❌ This syntax isn’t standard because the order should have the classes following the equal sign.

The ternary operator

<div class="block {condition ? 'font-normal text-base' : ''}" />
  • ✅ Supports multiple classes.
  • ❌ Includes boilerplate.

The && operator

<div class="block {condition && 'font-normal text-base'}" />
  • ✅ Supports multiple classes.
  • ✅ No boilerplate.
  • ❌ Can lead to unwanted classes like false, null, and undefined.

What is the solution?

Use the && operator and ignore adding classes like false, null, and undefined. However, it may be problematic because some developers may be using classes like is-open-{isOpen}!

Deprecate the class directive in Svelte version 4, because it’s not gonna be useful anymore.

Port is already in use

Automatically change the port to a random number if the current port is in use.

Dynamic HTML tags

Guess what? You can now use this cool feature! 👏

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

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

Sadly, there’s an issue; What if you also need to bind the element to a variable? Here’s an example:

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

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

What you’re observing are two props with the same name but different functionalities. It works, but it looks like we accidentally added the prop twice!

It would make more sense if they changed the name of the tag prop to tag. Here’s an example:

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

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

Documentation

Documentation content and the design needs a rewrite and a redesign. There is a lot of content missing. It’s the year 2023, and there is no dark mode feature. Algolia sucks because it’s not accessible in some countries like Iran, so you need to use a VPN to be able to use it.

No i18n support

Svelte and SvelteKit docs don’t support i18n. There are functionalities to add a new language or anything like that. Some developers even tried to create their own version of Svelte docs and translate it manually: https://github.com/svelte-jp/svelte-site-jp

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 files for I18N is not an optimal solution, as it can be difficult to manage and maintain. A better approach is to use PO (.pot, .po, .mo) files, which have been a standard format for translation files used by millions of developers and translators for years. This convention is not just limited to the PHP ecosystem, and can be implemented in Svelte as well. This approach can provide numerous benefits, including the ability to leverage community translations, AI-powered translation features, and tools like PoEdit for easier translation management. It’s also important to follow known standards, such as using __() syntax for wrapping translatable strings.

Dealing with error.html in SvelteKit

In SvelteKit, you come across a file named error.html. It’s a simple .html file where you can’t use the cool features of Svelte. You basically start from scratch, needing to manually add all your meta tags and other things. It’s not exactly exciting. Duplicating code isn’t my thing, and having to update it in two separate spots isn’t ideal either.


Return to top