npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

partial-hydration-sk

v1.3.0

Published

[Live demo with adapter-static](https://partial-hydration.gradientdescent.de)

Downloads

2

Readme

partial-hydration-sk

Live demo with adapter-static

Add partial hydration to your SvelteKit pages. It means that some parts of your page are only prerendered or rendered by the server. These parts are static, it won't change due to user interaction. This can be useful when:

  • large parts of your app are static and only few parts need javascript
  • rendering is expensive and can be performed only at server, eg. processing markdown files to html

Installation

npm i --save-dev partial-hydration-sk

Developing

You manually decide, which parts of your page are static and which parts need hydration. Static components need to be registered in server-side code. I'd recommend to add a file '+page.server.js', if you don't have one yet. In the 'load' function register the static Component:

import YourStaticComponent from '$lib/.../YourStaticComponent.svelte';
import {addPage} from 'partial-hydration-sk/server';

export async function load(){
    addPage({page:YourStaticComponent,name:"YourStaticComponent");
}

Somewhere in your dynamic page, usually in the '+page.svelte', you can load the static code:

<script lang="ts">
    import {PartialApp} from 'partial-hydration-sk';
</script>
<PartialApp tag="div" id="appstart" page="YourStaticComponent"/>

Note that "YourStaticComponent" is referenced by the name you've put in the 'addPage' function, it is not imported here.

Adding Hydration

Inside the static component, you can decide to add hydratable content. This would go into a separate Component and is wrapped into the 'Hydrate' component.

<!--inside YourStaticComponent.svelte-->
<script>
    import YourHydratableComponent from '.../YourHydratableComponent.svelte'
    import {Hydrate} from 'partial-hydration-sk';
</script>

...
    <Hydrate component={YourHydratableComponent}>
        <SomeMoreStaticCode>
    </Hydrate>
...

In addition, you need to tell the 'PartialApp' component, that you intend to hydrate your Component. There are two ways to do this:

1. +page.js

Register the component via the 'setDynamicComponents' function, eg. in 'load':

import {setDynamicComponents} from 'partial-hydration-sk'
    import YourHydratableComponent from '.../YourHydratableComponent.svelte'
export async function load(){
    setDynamicComponents([YourHydratableComponent])
}

'setDynamicComponents' accepts an array of SvelteComponents and functions, see lazy loading below.

2. Props

The 'PartialApp' component accepts a prop 'start':

<script lang="ts">
    import {PartialApp} from 'partial-hydration-sk';
    import YourHydratableComponent from '.../YourHydratableComponent.svelte'
</script>
<PartialApp tag="div" id="appstart" page="YourStaticComponent" starts={[YourHydratableComponent]}/>

Advanced Props Handling

You can only pass serializable (JSON.stringify) into the prop 'props' to the 'Hydrate' component. If you need more complex props, eg. if you want to put a function as prop, you can retrieve a store to the props from the 'PartialApp' component. Pass a unique key to the Hydrate component, so that you can retrieve the props:

<!-- +page.js -->
<script>
    import {PartialApp} from 'partial-hydration-sk'

    let hydrated,
        hydratedChildProps
    $: if (hydrated){
        const hydratedChild = hydrated.find(v=>v.key==="mykey");
        if (hydratedChild){
            hydratedChildProps = hydratedChild.props;
            hydratedChildProps.update(v=>({...v,someFunctionProp:()=>{...}}))
        }
    }
</script>
...
    <PartialApp bind:hydrated>
...
<!-- SomeStatic.svelte -->
...
<Hydrate key="mykey" ...>

Lazy Loading

You can delay the download of code and hydration. To do that, the array argument of the function 'setDynamicComponents' also accepts functions, which return a Promise:

import { setDynamicComponents } from 'partial-hydration-sk/pages';

export async function load(){
    setDynamicComponents(
        [
            async () => (await import('../LazyLoadedComponent.svelte')).default
        ])
}

In the static component, you can import the component directly:

<!--inside YourStaticComponent.svelte-->
<script>
    import LazyLoadedComponent from '.../LazyLoadedComponent.svelte'
    import {Hydrate} from 'partial-hydration-sk';
</script>

...
    <Hydrate component={LazyLoadedComponent} trigger="observer" key="mylazy">
        <SomeMoreStaticCode>
    </Hydrate>
...

If you omit the trigger prop or set it to "observer", the import and hydration is triggered by an intersection observer. Once the surrounding element is visible, it is hydrated.

Custom Trigger

Alternatively, you can set the 'trigger' prop to '"custom"'. Then you should also pass a unique key and retrieve a trigger function from the 'PartialApp' component. You can also retrieve a reference to the surrounding element, so that you can attach listeners to it.

<!-- +page.js -->
<script>
    import {PartialApp} from 'partial-hydration-sk'

    let hydrated,
        hydratedChildProps
        first = true;
    $: if (hydrated){
        const hydratedChild = hydrated.find(v=>v.key==="mykey");
        if (first && hydratedChild){
            first = false;
            hydratedChild.element.onclick = hydratedChild.element.trigger;
        }
    }
</script>
...
    <PartialApp bind:hydrated page="staticpage">
...

Limitations

Currently Svelte style tags work in static components. The styles are gathered and added inside a style tag within the body of the html file.

Example

You can find an example app here:

https://github.com/micha-lmxt/sveltekit-partial-hydration-template

Live demo with adapter-static