sveltejs / sveltejs/kit

Sveltekit server components

Open
#12,123 2 comments 3 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
JavaScript
Stars
20.8k
Forks
2.3k
Avg merge
1d 16h
Merged PRs (30d)
156

Description

Describe the problem

Until now I havnt found a way to get server components similar to htmx. One possible way is to put components in the router and use them like a route but it produces a large response size.

Describe the proposed solution

This javascript function kindof works
first I setup a components directory in routes, for example "routes/components/counter/+page.svelte"
then when I want to update the component I pass the destination element and request path to the function below and it successfully grabs the component and places it

    const getComponent = async (componentPath: string, target: HTMLElement) => {
        const res = await fetch(componentPath, {
            method: 'GET',
            headers: {
                // html content type
                'Content-Type': 'text/html'
            }
        });
        if (res.ok) {
            const parser = new DOMParser();
            const doc = parser.parseFromString(await res.text(), 'text/html');

            const scriptTags = doc.getElementsByTagName('script');
            const lastScriptTag = scriptTags[scriptTags.length - 1]!;

            const script = document.createElement('script');
            script.innerHTML = lastScriptTag.innerHTML;

            const teleportContent = () => {
                div.querySelector('#svelte-announcer')?.remove();
                target.replaceWith(...div.childNodes);
            };

            // create a div in body to hold the component with id of the component path
            const div = document.createElement('div');
            div.id = componentPath;
            document.body.appendChild(div);

            // wait for the component to be hydrated
            const observer = new MutationObserver((mutations) => {
                if (mutations[0].removedNodes.length > 0) {
                    observer.disconnect();
                    teleportContent();
                }
            });
            observer.observe(div, { childList: true });

            div.appendChild(script);
            div.remove();
        } else {
            console.error('Fetch error:', res.status);
        }
    };

The issue with this is that although it does support the use of stores and imports in the component (which is great!) it produces a large response for a relatively small component.
It would be great if the sveltekit team would add a more native and convenient solution that produces a smaller request. There are many directions this could go, I would love to see any of them happen.

Alternatives considered

I also tried setting htmx up, it worked but it was very clunky and not ideal for sveltekit in my opinion

How do I get it going?
do
npm install htmx.org && npm install -D typed-htmx

add this script in your app.html head

<script src="node_modules/htmx.org/dist/htmx.min.js"></script>

add this in tsconfig

"strict": true,
"types": [ "typed-htmx" ]

and this inside global in app.d.ts

declare namespace svelteHTML {
    interface HTMLAttributes extends HtmxAttributes {}
}
Importance

nice to have

Additional Information

No response

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Review the routes/components/counter/+page.svelte example, the fetch-based getComponent function, and the referenced app.html, tsconfig, and app.d.ts setup. The issue does not identify a specific entry point, implementation scope, or acceptance test, so the desired native server-component behavior and smaller response size need to be defined before work can begin.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, typescript
Domain
frontend, web-dev
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.