EmilTholin / svelte-routing

A declarative Svelte routing library with SSR support
MIT License
2.03k stars 182 forks source link

basepath in Router not working for Link #305

Open lucatmedmij opened 2 months ago

lucatmedmij commented 2 months ago

Custom basepath works for Route but it does not work for Link

This works

  <Router basepath="/web">
    <Route component={Home} path="/" />
    <Route component={About} path="/about"  />
  </Router>

This does not work, it gives link without basepath

  <Router basepath="/web">
      <Link to="/">Home</Link>
      <Link to="/about">About</Link>
  </Router>

I use svelte 4 with vite

package.json

{
  "name": "test",
  "private": true,
  "version": "0.1.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "vite build --base=./",
    "preview": "vite preview",
    "check": "svelte-check --tsconfig ./tsconfig.json && tsc -p tsconfig.node.json"
  },
  "devDependencies": {
    "@sveltejs/vite-plugin-svelte": "^3.1.1",
    "@tsconfig/svelte": "^5.0.4",
    "eslint": "^9.9.1",
    "svelte": "^4.2.18",
    "svelte-check": "^3.8.5",
    "tslib": "^2.6.3",
    "typescript": "^5.5.3",
    "vite": "^5.4.0"
  },
  "dependencies": {
    "svelte-routing": "^2.13.0"
  }
}
mihael commented 1 month ago

+1

mihael commented 1 month ago

The solution is in utils.js. Link uses the function resolve to create the links:

/**
 * Resolve URIs as though every path is a directory, no files. Relative URIs
 * in the browser can feel awkward because not only can you be "in a directory",
 * you can be "at a file", too. For example:
 *
 *  browserSpecResolve('foo', '/bar/') => /bar/foo
 *  browserSpecResolve('foo', '/bar') => /foo
 *
 * But on the command line of a file system, it's not as complicated. You can't
 * `cd` from a file, only directories. This way, links have to know less about
 * their current path. To go deeper you can do this:
 *
 *  <Link to="deeper"/>
 *  // instead of
 *  <Link to=`{${props.uri}/deeper}`/>
 *
 * Just like `cd`, if you want to go deeper from the command line, you do this:
 *
 *  cd deeper
 *  not
 *  cd $(pwd)/deeper
 *
 * By treating every path as a directory, linking to relative paths should
 * require less contextual information and (fingers crossed) be more intuitive.
 * @param {string} to
 * @param {string} base
 * @return {string}
 */
const resolve = (to, base) => {

Here's a working example of using basepath with svelte-routing Links:

<script>
let basepath="/shop"
</script>
<Router {basepath}>
  <Link to="./">Shop</Link></li>
  <Link to="orders">Orders</Link></li>
  <Link to="about">About</Link></li>

  <Route path=""><Shop {shop}/></Route>
  <Route path="/orders"><Orders {shop}/></Route>
  <Route path="/about"><About {shop}/></Route>
</Router>