rturnq / solid-router

A router for solid-js
MIT License
42 stars 1 forks source link

Routing error on reload #17

Closed nmrshll closed 3 years ago

nmrshll commented 3 years ago

With the example from the readme:

import { render } from "solid-js/web";
import { Switch } from "solid-js";
import { Link, MatchRoute, Router, pathIntegration } from "@rturnq/solid-router";

function Root() {
  return (
    <>
      <nav>
        <Link href="/">Home</Link>
        <Link href="/about">About</Link>
        <Link href="/widgets/1234">Widget #1234</Link>
      </nav>
      <main>
        <Switch fallback={<h1>404</h1>}>
          <MatchRoute end>index page</MatchRoute>
          <MatchRoute path="about">about page</MatchRoute>
          <MatchRoute path="widgets/:id">{(route) => <div>widget {route.params.id}</div>}</MatchRoute>
        </Switch>
      </main>
    </>
  );
}

function App() {
  return (
    <Router integration={pathIntegration()}>
      <Root />
    </Router>
  );
}

render(App, document.body);

When reloading from a subpage (e.g. on /about), I get a 404 error. image

This seems to happen regardless of the web server used (I've tried both with the server integrated to webpack and serving built static files with another web server)

What I would expect instead, is for the page to load, and land directly on the /about subpage.

  1. Is this the expected behavior ?
  2. Is there already a way I can fix this ?

Thanks in advance

rturnq commented 3 years ago

Since you are getting a 404 response from the server, this sounds like an issue with the server not serving your application for all possible routes. That is to say, the server doesn't have anything to server for /about when you really want it to serve the same thing as /.

I haven't used Webpack in a while but I think you want this option enabled for the dev server: https://webpack.js.org/configuration/dev-server/#devserverhistoryapifallback

For a server like Express you'll want to use a wildcard route path. For example this will serve ./dist/pub/index.html for all routes. You'll want to make sure that other route handlers, such as the static file handler, is configured prior:

app.get('*', function (req, res) {
  res.sendFile(path.resolve(__dirname, 'dist/pub', 'index.html')); // Point to your built index.html file
});

Alternatively, in Express, this will only serve ./dist/pub/index.html for the / path which means /about is not handled.

app.get('/', function (req, res) {
  res.sendFile(path.resolve(__dirname, 'dist/pub', 'index.html'));
});

I don't believe express.static can be configured to do this for you as simply maps the requested path in its target directory.

nmrshll commented 3 years ago

That's a good point you make, I can't actually expect the server to know about my front-end routing (it makes perfect sense now you say it, only I got used to this just working out the box with SSG frameworks like Sapper)

Wildcard route matching seems like what I need if I write a server to serve those files. And alternatively, I suppose if I want to serve this as static files, I need to investigate static site generation with solid, so that each route has an actual file corresponding to it.

Thanks a lot for the answer !