Skip to content

Add support for handleLoad hook on client and server hooks #9542

@Lms24

Description

@Lms24

Describe the problem

TL;DR: We (Sentry) propose handleLoad hooks for client and server to have a central hook to wrap users' load functions with common functionality.

Hi, Sentry SDK dev again 👋

As briefly mentioned in #9530, we're working on a dedicated Sentry SvelteKit SDK. Among a lot of other features, we want to instrument users' load functions to automatically capture performance data and errors during data loading operations. Our SDK currently provides a wrapper for load that users can use in the following way:

// +page(.server).js

import {wrapLoadWithSentry} from '@sentry/sveltekit'

export const load = wrapLoadWithSentry((event) => {
  // whatever users do here
  return {message: 'Hi'}
});

while in theory this works quite well, in practice, it is a rather cumbersome job for our users to wrap every load function with this wrapper to integrate Sentry with their Kit apps.

Describe the proposed solution

Therefore, we propose a new hook called handleLoad for both hooks.client.js as well as hooks.server.js. We came up with an API that's similar to the server-side handle hook:

// hooks.(server|client).js

export const handleLoad = ({event, resolve}) => {
  // Do things before `load` is invoked
  const result = resolve(event);
  // Do things after `load` is invoked
  return result;
}

This hook would run whenever a universal load function is invoked, be it on the server or on the client.

To support server-only loads, we propose an additional handleServerLoad hook which would obviously only run on the server. API-wise, it would be the same as handleLoad just with the ServerLoad typings.

Optionally (if you think this is a good idea), users could specify the sequence function just like for handle to chain multiple handlers

This way, we could instruct our users to just add a Sentry handler to this hook once, instead of going through all their load functions and wrapping them with our wrapper:

// hooks.(server|client).js
import {handleLoadWithSentry} from '@sentry/sveltekit'

export const handleLoad = handleLoadWithSentry()

// only in hooks.server.js
export const handleServerLoad = handleServerLoadWithSentry()

We'd be happy to contribute this hook ourselves or help you all out in any way we can!

Alternatives considered

As we think that instructing our users to manually wrap all load function is too cumbersome, there's only one alternative that doesn't require changes in SvelteKit:

We create a Vite plugin which at build time, would try to wrap load functions with our wrapper automatically. We're currently doing this in our NextJS SDK (with Webpack) to auto-wrap NextJS data fetchers but it proved to be quite brittle and error-prone. We started out by modifying the AST, which we quickly abandoned and moved to a more sophisticated solution. However, it still depends a lot on users' project setups and the framework being stable itself, making it tricky to maintain on our end. Also, this whole process is rather opaque to our users as they don't see what's happening in their source code. Furthermore, we're aware that certain Vite plugins for SvelteKit (e.g. Houdini) already generate load functions at build time, meaning that things like plugin order or other interference might become an issue. For the mentioned reasons we would like to avoid such a build-time solution if possible at all.

Generally speaking, creating the SDK for SvelteKit is a very enjoyable process, especially thanks to the already provided hooks. In the end we would love to be able to have everything runtime-Sentry-related in the two hooks files which would be very clean in our view and super easy to set up for our users. Leveraging hooks feels like the most SvelteKit-native approach to us and we'd love to see handleLoad becoming reality.

Importance

would make Sentry users' life much easier (and admittedly Sentry devs' lives as well ;) )

Additional Information

I already took a stab at implementing this myself in SvelteKit and I opened a PoC PR (#9543). I know I'm probably missing cases and the whole thing needs a proper review and tests but maybe it's a place to start. I'm happy to collaborate and continue working on this PR if you think we could add this hook to SvelteKit!

Also, if you have another idea how we could easily instrument load functions in one place, we're definitely up for suggestions :)

Thank you for taking this issue into consideration!

Metadata

Metadata

Assignees

No one assigned

    Labels

    feature / enhancementNew feature or requestneeds-decisionNot sure if we want to do this yet, also design work needed

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions