-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Enable package-provided routes #8896
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Some way to expose routes from a package would be a nice enhancement for things like @auth/sveltekit to take advantage of. Currently it exposes all the api routes through a handler so they don't exist as routes in the route tree which isn't ideal when you want to split into multiple functions at route boundaries |
This is something we've been missing as well for our Sveltekit app template and would love to see it implemented. I would imagine that for something like this to work, the Sveltekit router would first have to be enhanced to also support non-file-based routing, which would consequently also help with localized routing. |
This comment has been minimized.
This comment has been minimized.
I'd like to express my need for this too and believe this would enable a bunch of new use-cases by making svelte kit more composable. In case there would be some interest by the maintainers to start conceptual work on this topic, I'd love to contribute. My impression from some explorations in svelte-kit to make this possible was, that it would not be very hard. One way to open up the router e.g. could be to allow other vite-plugins accessing the internal manifest, extend it and offer a few convenience APIs, which could be equally composable as nuxt plugins/ modules. Here a few interesting ways (imo) this is being handled by other frameworks at the moment: NuxtApps can be extended in different ways:
import type { RouterConfig } from '@nuxt/schema'
export default <RouterConfig> {
routes: (_routes) => [
{
name: 'home',
path: '/',
component: () => import('~/pages/home.vue').then(r => r.default || r)
}
],
}
This might be very vue-oriented in terms of pattern (hooks), but I found the ability to hook into the setup process of nuxt very convincing and convenient. A plugin (what they call "module") registers itself as nuxt module which then calls The same pattern can be used to extend Nitro to add new API routes or route middlewares. export default defineNuxtConfig({
hooks: {
'pages:extend' (pages) {
// add a route
pages.push({
name: 'profile',
path: '/profile',
file: '~/extra-pages/profile.vue'
})
// remove routes
function removePagesMatching (pattern: RegExp, pages: NuxtPage[] = []) {
const pagesToRemove = []
for (const page of pages) {
if (pattern.test(page.file)) {
pagesToRemove.push(page)
} else {
removePagesMatching(pattern, page.children)
}
}
for (const page of pagesToRemove) {
pages.splice(pages.indexOf(page), 1)
}
}
removePagesMatching(/\.ts$/, pages)
}
}
}) FreshIn fresh plugins can add new routes or middlewares too: https://deno.com/blog/fresh-1.3#adding-routes-andor-middlewares-from-plugins function myPlugin() {
return {
name: "my-plugin",
middlewares: [
{
middleware: { handler: () => new Response("Hello!") },
path: "/hello",
},
],
routes: [
{
path: "/admin/hello",
component: () => <p>Hello from /admin/hello</p>,
},
],
};
} In a follow-up iteration they are planning to open this up even further: denoland/fresh#1602 (comment) const app = freshApp({
plugins: [
twindPlugin,
{
name: "my-inline-plugin",
setup(app) {
app.use(req => ...)
}
}
}); |
I just found another use case for this. As part of an application I'm working on, I created a fully spec-compliant OAuth authorization server in SvelteKit. This is really gruesome validation work, and something I wouldn't recommend doing unless you really know your way around authorization. If I had a way to provide this as a package to others, the ecosystem would benefit as a whole. @Rich-Harris maybe you can take another look at this issue at some point? 🙏 |
I am building reusable/publishable Smart UI components ( using Vercel AI SDK) that need associated server API ( |
Yes please, this is currently my #1 frustration with SvelteKit. I'm building a bunch of smaller sites for clients which share a lot of routes (RSS, blog, checkout, auth etc). It would be great to not have to manually keep routes in sync across sites as I make changes and improvements to individual routes. |
In general, it would be nice to have a programmatic way to define routes. This would allow libraries to export functions that take a svelte kit context as parameter and add routes to it. The function could be called by an app or a plugin to inject the routes. It would also allow app developers to quickly create routes within a single file, instead of having to create a folder and a file +server.ts, for each route. |
For those that are interested, this setup is roughly how https://github.com/evidence-dev/evidence is architected. The user brings a small number of files and the rest are provided by the library. In terms of implementation, it works around the described issue by scaffolding a hidden svelte kit app in a .evidence directory, and makes liberal use of fs.copyFileSync to put the user files into this app. When the users runs the app, they actually are running the app in the hidden directory. https://github.com/evidence-dev/evidence/blob/next/packages/evidence/cli.js |
This comment has been minimized.
This comment has been minimized.
Ah, that's a neat solution. I might steal it! |
Describe the problem
Please bear with me for a minute, explaining the rationale requires a bit of context.
I'm working on a (FOSS) SvelteKit-based ebook library app. It is built to run on all platforms SvelteKit supports, with platform-specific integrations being used where possible. If you'd be running it on Cloudflare, for example, the Cloudflare R2 bucket integration will be used for storage; if running on Node, it will use the local filesystem. On a platform like Netlify, which has support for edge functions, book metadata parsing will run on the edge; whereas on other platforms, it'll use a web worker for that.
In addition to platform features, there are a bunch of other modules with configurable implementations (mailing, knowledge graph queries, image uploads, etc.).
Now, to make it easier for users to get started, as well as keeping runtime size small, I have an npm create package that will prompt the user for the services they use, and perform a custom install of all required packages: Say,
@example/core
,@example/mailing-mailgun
, and@example/storage-cloudflare
(and their respective dependencies).All of this works; what I'm missing, however, is a good way of packaging up the actual SvelteKit app in a reusable way. Right now, I have to copy all project files from a template repository into the user's project directory, install dependencies, and generate a matching .env file.
On the plus side, this gives users something of an improved git clone, essentially a glorified configuration script. They can modify all routes and components to their liking.
On the downside, this setup is incredibly hard to reliably update, and requires anything and everything to have a stable API.
Describe the proposed solution
What I envision is the ability to distribute my SvelteKit app as a dependency users would install into an empty project, along with any extension packages they need. The project would start with an empty
src/routes
directory; all routes would be loaded from the base application, unless a file with the same path exists in the routes directory. For example, my app would provide an implicit/profiles/[user]
route, which users could eject/override by creatingsrc/routes/profiles/[user]/+page.svelte
. (Thanks to @theetrain on Discord for putting it so succinctly). Obviously this still bears the risk of ejected routes breaking after updates, but in that case it's immediately clear whether a bug is caused by userland or package code.This would make for a very small installation footprint, while still being hackable.
From a technical POV, this would probably work best as a Vite plugin that overlays SvelteKit, as in
plugins: [ kit(), app() ]
. I have dabbled with Vite, but definitely not enough yet to do this on my own, however.Alternatives considered
Having users
git clone
a starter repository, or copying a starter project using the create package both work, but come with the aforementioned downsides (namely the complexity of updates and support headaches).Importance
would make my life easier
Additional Information
The project is still a work in progress, although the repository shows the structure I'm going for, if that helps:
https://github.com/project-kiosk/kiosk/tree/next#readme
The text was updated successfully, but these errors were encountered: