Sapper: Multiple routers (e.g. for subdomains)

Created on 12 May 2019  路  9Comments  路  Source: sveltejs/sapper

I'm building a SSR app which behaves differently on different domains.
The main domain is a landing/registration site, where users register subdomains. Then, the subdomains are login/main app sites which have completely different set of pages.

For example:
https://acme.com/
https://acme.com/about
https://acme.com/register
https://acme.com/login -> 404
https://foo.acme.com/
https://foo.acme.com/login
https://foo.acme.com/stats
https://foo.acme.com/about -> 404
https://bar.acme.com/
https://bar.acme.com/login
https://bar.acme.com/stats
https://bar.acme.com/about -> 404

Is there currently a way to handle this setup with Sapper? I realise that I can create two independent Sapper apps but then for instance the vendor code or CSS will not be reused. Also, the development environment will not be friendly as the two servers will need to be started on different ports.

(The current version of the app runs on Vue with Ream SSR. When I had needed that functionality, I developed fs-routes plugin which is capable of being injected several times with different setup, and came up with simple server and client middlewares to pick the proper router. I'm happy to contribute to Sapper if that is needed, but the initial guidance would be helpful.)

Most helpful comment

@MatthiasGrandl No. For now, I disregarded the idea of porting the project in the original question to Svelte. Honestly, the more I work with Svelte (with the other project that only needs 1 router) the more I don't like it, it seems to be quite limited architecturally and the worst thing is that authors/maintainers don't seem to accept that.

A couple of other examples for which I participated in discussions:

There's much more than that.

Even though the idea behind Svelte is nice, the implementation - in my thinking - is sub par.

All 9 comments

I have the same question. I found that it is possible to override routes directory to have a different routes structure for each sub-application. For example I can run npx sapper build --routes=src/routes-foo and it works good for me. Unfortunately when I do the same in dev mode npx sapper dev --routes=src/routes/routes-diply there is an error As of Sapper 0.21, the routes/ directory should become src/routes/.

@IlyaSemenov actually I was wrong. It is possible to have multiple route trees using --routes key for building bundle. The error appeared just because I did not provide the key properly.

Yeah but I don't want to have multiple sub-applications for the reasons I stated above:

  • no code reuse between the sub-apps
  • more complicated dev environment with 2 dev servers running on different ports

I'd like to have a single app with 2 routers and choose the router dynamically per request with some kind of middleware (on server, it will decide based on req.headers.host, and on client it will either lookup location.hostname or - better - use a value injected into __SAPPER__ by server-side middleware). I'm doing exactly so on Vue right now.

Maintaining 2 routers, although lesser evil than maintaining 2 apps, still causes you to split your codebase into separate logical chunks. Instead, a better option might be to have one router in your app but offer route masking. That allows you to have both nice URLs for your domain and subdomains while offloading the logic to a server layer in front of the app.

This is however not possible in Sapper yet but is a functionality of NextJS. We might consider exploring this, for use cases such as yours.

Yes, having a single router, putting all app URLs under a common prefix (e.g. /app/), and auto-prefixing URLs on subdomains with some means will work as well.

I am not exactly sold on NextJS route masking, as it's tedious to write <a href="/stats" as="/app/stats"> everywhere, but may be I'm missing something here.

In either case, I just wanted to describe a valid use case that I'm missing with Sapper, and now that you saw and understood it, that should be it, thanks!

I don't think we're going to support completely independent routers, but we probably are going to support something like #735, where the preloads and the page store have access to the current page's host (which is determined from req.headers.host on the server and from location.host on the client).

So how do I handle the use case explained in the issue description? Is it deliberately not allowed?

@IlyaSemenov did you figure it out? Would also love to know the answer.

@MatthiasGrandl No. For now, I disregarded the idea of porting the project in the original question to Svelte. Honestly, the more I work with Svelte (with the other project that only needs 1 router) the more I don't like it, it seems to be quite limited architecturally and the worst thing is that authors/maintainers don't seem to accept that.

A couple of other examples for which I participated in discussions:

There's much more than that.

Even though the idea behind Svelte is nice, the implementation - in my thinking - is sub par.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Rich-Harris picture Rich-Harris  路  4Comments

BMorearty picture BMorearty  路  3Comments

benmccann picture benmccann  路  3Comments

Rich-Harris picture Rich-Harris  路  3Comments

freedmand picture freedmand  路  4Comments