kit
kit copied to clipboard
allow `config.kit.files.routes` to be an array of directories
Describe the problem
We have a multi-tenant SvelteKit project, with a directory structure like following:
src/routes/
- index.svelte
- about.svelte
- terms.svelte
- [...project1]/
- index.svelte
- [...project2]/
- about.svelte
Here, we've many common routes (index, about, terms). Each project can override the common routes with a few of their custom routes (like project1
has its own index.svelte
but uses the common about.svelte
; and project2
has a different about.svelte
but uses the common index and terms page.
Before we had the new routing system (https://github.com/sveltejs/kit/discussions/5774), we could filter out specific files from routes directory to be considered for routing using the config.kit.routes
function. This was done based on build-time env variables like following:
routes(filepath) {
const currentProject = process.env.PROJECT_ID;
// Exclude special folder that doesn't match current project.
const re = /^\/\[\.\.\.(project1|project2)\]/;
if (re.test(filepath) && filepath.match(re)[1] !== currentProject) {
return false;
}
// If we've a matching route in currentProject-specific folder, exclude the common
// filepath route. We'll end up using currentProject-specific one as `params[currentProject]` can
// be an empty string, which SvelteKit router matches.
// This does mean `/anything/foo` as well as `/foo resolve to same page,
// but we can exclude `/{anything}/foo` using route params. Hacky, but works.
const specialRoute = path.join(`src/routes/[...${currentProject}]`, filepath);
return !existsAsFile(specialRoute);
},
Now, the config.kit.routes
option has been removed and we can't upgrade to newer versions without major changes to our approach.
Describe the proposed solution
- Bring back
config.kit.routes
option. - Support multiple directory in
config.kit.files.routes
, which can support overrides like above. This is arguably a niche use-case, but would love if this can be supported.
Alternatives considered
We can create multiple top-level routes directories and symlink/hardlink the common routes to project-specific directory, while avoiding the existing non-symlink project-specific files, to have a directory structure like:
src/
- routes.common/
- index.svelte
- about.svelte
- terms.svelte
- routes.project1/
- index.svelte
- about.svelte <symlink>
- terms.svelte <symlink>
- routes.project2/
- index.svelte <symlink>
- about.svelte
- terms.svelte <symlink>
But this might cause confusion, where we update one file and it unexpectedly ends up updating other file too. Also, it will require us to delete the symlink and create a regular file when we want to override a route.
Importance
would make my life easier
Additional Information
No response
Using routes
for this is the sort of creative hackery that I very much enjoy. That said, it is hackery, and not a good reason by itself to reinstate the feature, I think.
What about this as an alternative? The basic idea is that you start SvelteKit (dev or build) like so...
PROJECT=project-1 pnpm dev
...and it creates a new routes
directory there and then that combines the default files with the overrides. If no PROJECT
is specified, it defaults to using src/routes
.
Obviously I'm glossing over some details (e.g. you would probably want to watch the src/project-{n}
directories during dev to update the generated routes
directory) but this feels like a better match between intention and outcome than abusing rest parameters, which feels like it will inevitably cause gotchas further down the line.
Thanks for the quick reply, @Rich-Harris! Indeed, it is hackery.
What about this as an alternative?
Yeah, that's the alternative I was considering (but with symlinks instead and not removing the project dir as it contains the override routes).
Though, what are your thoughts on supporting multiple folders in config.kit.files.routes
?
I can see it being a potentially quite valuable addition. It would add some more moving parts though, and the aftershock of #5748 is still reverberating through the codebase — lots of small follow-up work that needs to happen — and so now would be a challenging time to make those sorts of changes.
Once we ship 1.0 and have a more stable base work on top of I think we should revisit this.
@Rich-Harris Can this be re-visited now that it's post-1.0 😊 ?
I have a similar use case, but nothing as exotic as having two projects - I'm generating a static site with adapter-static
, but I also have an admin
route that I'd like to exclude during the build. Right now the workaround is to rm -rf src/routes/admin
to build, but that's pretty hacky.
I have a similar use case - I want to be able to share routes between multiple projects. For example, let's say I create a Blog package that I want to include in multiple projects with the minimum boilerplate/wiring-up possible (and ultimately to be able to share that package with the public).
All the components and source files in $lib come over nicely, that's great. But the routes need to be re-created in some way for each project that uses the package. And while for a simple package like a Blog that isn't too much hassle, for something more complex like an e-commerce system, re-creating the routes - and dealing with updates to the shared packages - for each project becomes a problem.
A solution like OP is describing would be incredibly helpful and I think would be a real boon for the Svelte ecosystem as we would be able to share share full functionality more easily and allow for more "batteries included" projects to be built on top of SvelteKit.
I am migrating from express where I have a user module that handles all my user logic, routes, etc. and I just "plug in" to each project. I was looking for how to do this and stumbled on this thread. Being able to slice applications vertically and share them between projects. At present I can share the logic, and the lib components, but I have to recreate routes and pages which is a pain.
I've a similar use case and such a possibility would be very helpful: I'm creating a backoffice application and as always there's a lot of similar screens in those that directly depend on the data model.
In order to save time in the long run I'm setting things up to use code generation in all layers on my stack, which includes generating svelte pages and components.
For the later it is quite simple to have one $lib
directory and one $generated
, though the same doesn't apply to routes.
I would like to be able to have two folders (e.g. src/routes
and generated/routes
) which contain the manually defined and automatically generated routes. Currently I don't seem to find an efficient way to do so with SvelteKit.
Just found a workaround: put all generated routes in a (generated) group which serves only the purpose to have them under a single folder so its content can be ignored by git. Not ideal but seem to do the job for now.
Is this by any chance implemented in SvelteKit 2.0?
Is this by any chance implemented in SvelteKit 2.0?
I don't think so, I'm using Svelte 2.4.3 and the config.kit.files.routes
options is a string.