A library of web components built with Svelte 5. This library provides reusable web components that can be used in any JavaScript framework or vanilla HTML.
# Original install command for Svelte 5
pnpm create vite@latest
Partially built with WindSurf IDE. See : https://www.youtube.com/watch?v=0g1NPN4aPBI
pnpm add github:dlaxcess/webcomponentSvelte5
( Open test.html or test-individual.html in your browser ) You can import and use the components in two ways:
<script type="module">
import "./dist/webComponentSvelte5.es.js";
</script>
<script type="module" src="./dist/components/counter.js"></script>
<script type="module" src="./dist/components/counterDisplay.js"></script>
Then use them in your HTML:
<!-- Counter component with custom header -->
<counter-component buttonheader="My Counter"></counter-component>
<!-- Counter display component that shows the current count -->
<counterdisplay-component></counterdisplay-component>
<!-- Counter display with slots -->
<counterdisplay-component>
<div slot="description">
<h2>My Custom Counter</h2>
<p>With reactive update</p>
</div>
<div slot="footer">
<hr />
<small>Created with ❤️</small>
</div>
</counterdisplay-component>
// App.jsx
import "webcomponentsvelte5/components/counter";
import "webcomponentsvelte5/components/counterDisplay";
function App() {
return (
<div>
<counter-component buttonheader="My Counter"></counter-component>
<counterdisplay-component></counterdisplay-component>
</div>
);
}
export default App;
See a complete SvelteKit integration example here: svete5import
⚠️ Web Components are not compatible with Server-Side Rendering out of the box. Below are examples of how to properly integrate them in SSR frameworks.
"use client";
import dynamic from "next/dynamic";
import { useEffect, useState } from "react";
// Create a client-side only component
const Counter = dynamic(
() => {
import("webcomponentsvelte5/components/counter");
return Promise.resolve(() => <counter-component buttonheader="My Counter" />);
},
{ ssr: false }
);
const CounterDisplay = dynamic(
() => {
import("webcomponentsvelte5/components/counterDisplay");
return Promise.resolve(() => <counterdisplay-component />);
},
{ ssr: false }
);
export default function HomePage() {
const [isClient, setIsClient] = useState(false);
useEffect(() => {
setIsClient(true);
}, []);
if (!isClient) {
return null; // or a loading placeholder
}
return (
<div>
<Counter />
<CounterDisplay />
</div>
);
}
For a complete SvelteKit integration example, see: svete5import
Here's a basic wrapper component for SvelteKit:
// lib/componentsWebComponentWrapper.svelte.d.ts
declare module "$lib/components/WebComponentWrapper.svelte" {
import type { SvelteComponent } from "svelte";
export default class WebComponentWrapper extends SvelteComponent<{
// Add props here if needed
}> {}
}
<!-- lib/componentsWebComponentWrapper.svelte -->
<script lang="ts">
import { browser } from "$app/environment";
import { onMount } from "svelte";
let mounted: boolean = false;
onMount(async () => {
if (browser) {
await Promise.all([
import("webcomponentsvelte5/components/counter"),
import("webcomponentsvelte5/components/counterDisplay")
]);
mounted = true;
}
});
</script>
{#if mounted}
<slot />
{/if}
<!-- Usage in your pages -->
<script>
import WebComponentWrapper from '$lib/components/WebComponentWrapper.svelte';
</script>
<WebComponentWrapper>
<counter-component buttonheader="My Counter" />
<counterdisplay-component />
</WebComponentWrapper>
The components communicate through custom events:
counter-update
: Emitted when the counter value changesdocument.addEventListener("counter-update", (e) => {
console.log("New count:", e.detail.count);
});
# Install dependencies
pnpm install
# Build the library
pnpm run build
MIT dlaxcess