Adapter hooks/plugins
See original GitHub issueDescribe the problem
If a developer wants to add functionality to an adapter, they must create a new adapter. This has a handful of drawbacks, including:
- Adapters are limited by what the
builder
object exposes to theadapt()
API - New adapters don’t benefit from updates to existing adapters
- Adapters don’t benefit from modular, shared components – if an adapter doesn’t already do exactly what the dev wants, they’ll have to make their own
My specific example of this is that I want the following features in a static adapter:
- Upon rendering of each page, I want to trigger creation of a preview image (for e.g. social media previews) for that page
- Upon completion of rendering all pages, I want to create a Sitemap from the list of all rendered pages.
Currently I can only do this by first waiting for the build process to come to an end (e.g. via a CLI command like svelte-kit build && create-preview-images && create-sitemap
) or by creating a new adapter based on the official static adapter.
Describe the proposed solution
Adapters are already expected to fit a specific API and perform a common set of tasks, so it would be possible to implement hooks/plugins to bypass the need to create new adapters.
Possible hooks include:
- Before the adapter starts
- After the adapter completes
- Before prerendering starts
- After prerendering completes
- Before each page is pre-rendered
- After each page is pre-rendered
These could each be managed in the config where they make the most sense. This might look like (in pseudo-Typescript):
import type {Config, Adapter} from '@sveltejs/kit';
interface AdapterWithHooks extends Adapter {
begin: (info: any /* maybe `builder` or other context info */ ) => void;
end: (info: any) => void;
}
interface ConfigWithAdapterHooks extends Config {
kit: {
prerender: {
begin: (info: any /* {cwd, ...} */ ) => void;
beforeEach(info: any /* {cwd, currentFile, ...} */ ) => void;
afterEach(info: any /* {cwd, currentFile, ...} */ ) => void;
end: (info: any /* {cwd, renderedFiles, ...} */ ) => void;
};
adapter: AdapterWithHooks;
};
}
I’m not sure exactly what the arguments to these hooks should be, nor what they should return. To make them as shareable and composable as possible, multiple hook functions could be provided for each event.
Alternatives considered
An alternative would be to use a basic event-based system, even one without payloads, so that developers can trigger custom functionality at appropriate times. For example, each builder
function could emit when called, with whatever payload makes sense in that context.
This would prevent the developer from being able to change what the adapter is doing, but that isn’t necessarily a bad thing.
Both the proposed and alternate solutions allow for incremental and independent feature addition. E.g. an end
hook could be implemented that gets called after the adapter completes, even if no other hooks have been added.
Importance
would make my life easier
Additional Information
No response
Issue Analytics
- State:
- Created 2 years ago
- Comments:7 (5 by maintainers)
Update: Today I published a copy of the static adapter package which includes hooks. You can find the package here: https://www.npmjs.com/package/@ivorgri/sveltekit-pluggable-static-adapter. With that package, you can add functions to your adapter, which run after the cleanup, prerender and the compress steps within the build of the static adapter. I’ve also created three plugins:
I still need to write the documentation for all of the plugins and the adapter, but it really boils down to adding the following code to svelte.config.js.
Hope this helps and is a basis for a change in the static adapter. Any input is welcome! Thanks for planting the seed @adam-coster .
I was referring to the hot-reloading process, where a page gets rebuilt during development. The static adapter re-renders a page when it gets modified during development.
I’ve since moved the post-build processes into Vite plugins, so I no longer have a need nor any strong opinions about having hooks built into adapters.