sveltejs / kit

web development, streamlined
https://svelte.dev/docs/kit
MIT License
18.73k stars 1.94k forks source link

Hash based routing #7443

Open alvarolm opened 2 years ago

alvarolm commented 2 years ago

Describe the problem

I love the flexibility that svelte kit provides, in fact I think that is one of the main selling points, it seems there are no restrictive impositions.

Sadly for those who just want to deploy a static spa application (don't care about seo) that requires no major server configuration svelte kit is not the right choice at the moment. I believe this is a critical issue since portability and no vendor lock-in (server side) are imperative for many.

So far the only impediment that I see is routing.

Describe the proposed solution

hash based routing would resolve exclusively from the client side without any configuration from the server

Alternatives considered

No response

Importance

i cannot use SvelteKit without it

Additional Information

https://github.com/sveltejs/kit/pull/6625 https://github.com/sveltejs/kit/pull/6594 https://github.com/sveltejs/kit/issues/7244 https://github.com/sveltejs/kit/issues/3852

didier commented 2 years ago

Just curious: what's preventing you from just using the static adapter? Slash-based 'real' routes are usually better UX than anything hash based.

If you do want to go the hash route (no pun intended) there are many packages on npm for just that.

fehnomenal commented 1 year ago

I'm about to build a widget that will get embedded in bigger pages (most probably wordpress pages but also manually written html pages). The widget will consist of multiple "screens" that get and post information to our API. It will also be completely client-side rendered - a SPA embedded inside a layout that I have no control over.

This also means I cannot use kit's default routing as I cannot force the customers to configure their server/site/whatever to correctly serve the fallback file of the static adapter which is a problem if the user reloads the page.

Of course I could just use plain svelte with any routing library but I'd love to take advantage of kit's layouts, load functions and all the other stuff I love about it.

igorsantos07 commented 1 year ago

Also came here quite surprised (or maybe not, given SvelteKit is opinionated and there's nothing wrong with that) that it's not possible to enable hash-based navigation.

My use-case is I'd like to deploy a simple SPA without needing to care for server rendering and all, but still leverage the cool routing ideas and layout reutilization that SvelteKit provides.

As far as I can see, once the main code is loaded from the SPA side (i.e. using @sveltejs/adapter-static), the "only" thing that would need changing is the interpretation of window.location?

lamualfa commented 1 year ago

Just curious: what's preventing you from just using the static adapter? Slash-based 'real' routes are usually better UX than anything hash based.

If you do want to go the hash route (no pun intended) there are many packages on npm for just that.

The slash-based route doesn't work in a single endpoint environment such as Electron.js. That's why many router libraries like react-router or @tanstack/react-router add hash-based route support for the usage.

boustanihani commented 1 year ago

For now, there is no "production ready" hash based router that supports svelte 4. It would be nice, if sveltekit supports hash based routing (or switching to a hash based mode). Ideally this should simply be enabled in a config file, and all routes become hash based, also for existing projects...

scottkuhl commented 1 year ago

Like the comment about Electron, this is also an issue if you want to use SvelteKit routing in a browser extension.

NatoBoram commented 11 months ago

Use case: a static build for IPFS. There's no server on IPFS. There's not even a GitHub Pages one or even an Electron wrapper that can redirect to 404.html. Not only that, but you can't know beforehand the config.kit.paths.base until the thing is built since it's content-addressed.

You can use adapterStatic({ fallback: 'ipfs-404.html' }) with great success, but as soon as you have a dynamic route inside of a static route, links aren't going to work anymore. I guess another solution could be to simply duplicate the fallback file inside every single static route...

FranklinWaller commented 11 months ago

IPFS is the biggest use-case for me. There is no other way to render than using hash based routing.

multiplehats commented 8 months ago

I'm a WordPress plugin developer, and I'd love to use SvelteKit to build admin settings, this approach however requires hash based routing.

chrisvire commented 2 months ago

I have a desktop app (https://software.sil.org/scriptureappbuilder) which has historically been a no-code builder of Android and iOS Apps. I have adapted it to use a PWA template (https://github.com/sillsdev/appbuilder-pwa) which is a SvelteKit PWA that takes generated files from the desktop app (in the /data folder) and transforms it to be used by the PWA.

It common to have hundreds of projects (for many languages) that are hosted in sub directories of a website. As part of the build process we get the base from environment:

svelte.config.js

import adapter from '@sveltejs/adapter-static';
import { sveltePreprocess } from 'svelte-preprocess';

/** @type {import('@sveltejs/kit').Config} */
const config = {
    // Consult https://github.com/sveltejs/svelte-preprocess
    // for more information about preprocessors
    preprocess: [
        sveltePreprocess({
            postcss: true
        })
    ],

    kit: {
        adapter: adapter({
            fallback: 'index.html'
        }),
        paths: {
            base: process.env.BUILD_BASE_PATH
        }
    }
};

export default config;

Here is an example: https://bible.thehubbards.org/web/pwa/

What we have noticed is that if someone is at a route (like /settings or /text), if they refresh the page then the server sends a 404 since it doesn't know about /web/pwa/settings or /web/pwa/text).

I have worked around this by deploying this .htaccess file:

RewriteEngine On

# Ensure the request is not for an actual file or directory
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

# Capture the language and PWA name, and rewrite everything back to /lang/pwa/
RewriteRule ^([^/]+)/pwa(/.*)?$ /$1/pwa/ [L]

I really don't like requiring the person deploying the PWA to handle this in the web server config (it may be restricted?). I see one solution is to use hash-based routing. Is there another way?