Sveltekit server components
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
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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