mefechoel / svelte-navigator

Simple, accessible routing for Svelte
Other
504 stars 39 forks source link

How do i get the current location globally in my App.svelte? #40

Closed Alfagun74 closed 2 years ago

Alfagun74 commented 3 years ago

I wan't to store the current location e.g. ("/path") globally in my App.svelte to check on which path i am. How do i accomplish this is there something like a reactive "currentLocation" i can use? I didn't fnd anything in the documentation unfortunately.

Alfagun74 commented 3 years ago

should i just use window.location.pathname?

mefechoel commented 3 years ago

If you are inside a Router you can always use useNavigate to get a store with the current location. If you really need to access it outside the main Router, you can import globalHistory. You can access the current location via its location property. If you want a reactively updated value, you can subscribe to changes in location via its listen function. It works the same way as the subscribe method on svelte stores, so to get a readable store from it, this should work:

import { globalHistory } from "svelte-navigator";

const historyStore = { subscribe: globalHistory.listen };

listen gets called with an object containing action, which is the kind of action that lead to the navigation (PUSH, REPLACE or POP) and the updated location. Since you only care about the location you could use svelte's derive function to map the navigation update to the location if you like.

mefechoel commented 3 years ago

As a side note, it's always best to avoid using window.location when working with spa routing libraries. There is no guarantee the browsers location and the routers location are completely in sync. Furthermore, when serving an app from a subdirectory on a server, the router might hide parts of the pathname from you. When you specify a basepath in svelte navigator for example, it will translate urls from /my-basepath/home to /home for you. This is not reflected in window.location however...

Vanderscycle commented 2 years ago

If you are inside a Router you can always use useNavigate to get a store with the current location. If you really need to access it outside the main Router, you can import globalHistory. You can access the current location via its location property. If you want a reactively updated value, you can subscribe to changes in location via its listen function. It works the same way as the subscribe method on svelte stores, so to get a readable store from it, this should work:

import { globalHistory } from "svelte-navigator";

const historyStore = { subscribe: globalHistory.listen };

listen gets called with an object containing action, which is the kind of action that lead to the navigation (PUSH, REPLACE or POP) and the updated location. Since you only care about the location you could use svelte's derive function to map the navigation update to the location if you like.

I didn't want to create a new issue but one of the application is when using modals and close on route change for example. When that's the case you have to put the logic inside the parent component calling the modal (I think). Anyway, Router works very well but svelte-simple-modal was having issues closing on route cahnge

  const historyStore = {
    subscribe: globalHistory.listen,
  };
  const unSub: Unsubscriber = historyStore.subscribe(() => {
    close();
  });
{... mroe svelte code}
  onDestroy(unSub);

I also just want to say that this router is amazing. Thank you for your work.