mefechoel / svelte-navigator Goto Github PK
View Code? Open in Web Editor NEWSimple, accessible routing for Svelte
License: Other
Simple, accessible routing for Svelte
License: Other
In the docs, this line of code:
const location = useLocation();
seems to redeclare the global location
(window.location
). Maybe this should use a different name that doesn't already exist in the browser?
Describe the bug
I can't render a route and its parent, comparison to the outlet concept of react-router
To Reproduce Steps to reproduce the behavior:
<Router>
<Route path="/*" component={Layout}>
<Route path="pvp" component={Pvp} />
</Route>
</Router>
Navigating to /pvp will render Layout correctly but won't render Pvp at all
Desktop (please complete the following information):
Additional context
Maybe I just didn't understand if it's possible and how to do it
Describe the bug
On navigation title is highlighted. Looks worse than the attached screenshot when used with bootstrap. I could not figure out what is that outline.
To Reproduce
Steps to reproduce the behavior:
Expected behavior
The outline should not appear
Screenshots
attached, see the outline on "Login" title
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.
π I have a question regarding the focus handling. I found it to be a bit distracting in my app. Instead of disabling it altogether through <Route primary={false}>
, I instead hid the focus outline for all elements like so:
<style>
/* App.svelte */
:global(:focus) {
outline: none;
}
</style>
I tried out the result in the Screen Reader Chrome extension and it seems to work as intended, ie. the element still pulls focus but without visual indication. I understand that losing a visual cue can be disorienting for some users, but are there any accessibility concerns in terms of screen readers when hiding the outline as above?
Hi there! How can I redirect a user after he clicks the if button? The Navigate method only works when replace is enabled, otherwise only the URL changes and the page remains the same
Describe the bug A clear and concise description of what the bug is.
visuallyHiddenStyle
in a11y.js
should include an initial position of bottom: 0
. Without it, it renders under (or sometimes besides) elements in the Router
causing scrollbars to appear.
To Reproduce Steps to reproduce the behavior:
div
with style of height:100vh
with Router
.Please add a link to an example in the Svelte REPL or in a Codesandbox, if you
can.
https://svelte.dev/repl/b4d98fdee025474291747a40a4ed32a7?version=3.31.2
Expected behavior A clear and concise description of what you expected to
happen.
No scrollbar or abnormal sizing issues.
I want reload my script, for example Home.svelte, in my case must reload Home.svelte
I try navigate does not work
How to do it ?
I have a Svelte app where I can set errors into a store, and they will show up on the page. However, the errors persist after changing the page. It would be handy to have navigate hooks to clear the errors before the page navigates (either via Link click or navigate api). The ability to perform some actions after navigate could also be potentially useful, e.g. scrolling to a specific part of the page if needed.
Suggested improvement:
<Router hook:beforeNavigate={clearErrors} hook:afterNavigate={scrollPage}>
...
</Router>
It could also be used for things like stopping navigate if a form is unsaved. If a beforeNavigate hook returns false, then the navigation should not proceed.
Add Router modules that are bound to a specific history:
Svelte Navigator gives you a lot of accessibility improvements out of the box, but for an even better experience the user needs to tailor focus management manually.
A common and apparently very useful technique to improve a11y is the usage of skip links.
This is described further in this blog post by Marcy Sutton on the results of user testing different a11y approaches.
It might not be obvious how to implement the technique with Svelte Navigator, so it should be broken down in an example.
How do you do a 404 page for routes that don't exist?
I"ve tried a Route with no path (just as svelte-routing suggest) with no success
<Router>
<Route path="blog">
<Blog />
</Route>
<!-- ... the rest of your routes -->
<Route>
<!-- Your 404 component -->
<NotFound />
</Route>
</Router>
any idea?
Is your feature request related to a problem? Please describe.
To have guarded some routes(admin, user, ...) something like angular router, so function which determines if the route can be activeted
Describe the solution you'd like
<script lang="ts">
function canActivate():boolean {
}
</script>
<Router {basepath}>
<main>
<Navbar />
<Route path="queries" component={Queries} />
<Route path="statistics" component={Statistics} canActivate={canActivate}/>
<Route path="status" component={Status} />
</main>
</Router>
Describe alternatives you've considered
<Router {basepath}>
<main>
<Navbar />
<Route path="queries" component={Queries} />
{#if canActivate}
<Route path="statistics" component={Statistics} />
{/if}
<Route path="status" component={Status} />
</main>
</Router>
Is your feature request related to a problem? Please describe.
No.
Describe the solution you'd like
Something like:
import * as navigator from 'svelte-navigator';
navigator.beforeNavigation((route, location) => new Promise);
This will alow something like a progress bar. I also don't want the current route content to be empty while progressing.
Describe alternatives you've considered
Firstly, thanks for creating this module - it's been a great help with creating my first couple of Svelte apps :)
In my latest app I've implemented the private route guard as in the example, and it works great when checking a simple bool or object on the store.
My auth requires an async call (to establish a JWT refresh on page reload), but I can't quite work out how to fit it in.
I thought I could use onMount, but that seems to be called after the reactive declaration. I also tried another 'checking' route that the private route could forward to on first load/browser refresh - which I would aim to handle the async check, but couldn't get that to work either.
Do you have an example how I might do this? Or if you can point me in the right direction, that would be much appreciated.
My current code looks like this:
import { onMount } from 'svelte';
import { useNavigate, useLocation } from 'svelte-navigator';
import { checkAuthStatus, isAuthenticated } from '../stores/auth';
const navigate = useNavigate();
const location = useLocation();
const navigateToLogin = () => {
navigate('/login', {
state: { from: $location.pathname },
replace: true,
});
};
onMount(async () => {
try {
await checkAuthStatus();
} catch {
navigateToLogin();
}
});
$: if (!$isAuthenticated) {
navigateToLogin();
}
</script>
{#if $isAuthenticated}
<slot />
{/if}
I have this weird bug where as soon as I add svelte-navigator to my page the focus is messed up.
The focus is on the first H1 which gets an ugly black border. Even an input with autofocus
or onMount(() => myInput.focus());
won't take away the focus...
Reproduce here: https://svelte.dev/repl/5c7cd0c49b2f47ac8532ab87e745cd95
I'm just wondering if I do something wrong here.
BR Matthias
Is this something evil or can it be supported?
{#if $userDataStore}
<Route path="/" component="{Home}" />
{:else}
<Route path="/" component="{Feed}" />
{/if}
Thank you for this library!
I'm looking for something like React routers Prompt.
When there is unsaved work there are three ways the user should be warned:
window.onbeforeunload
: The user presses refresh in the browser or navigates to another websitenavigate
: The user presses on an internal link that will change the page in the routerpopstate
: The user presses back in the browser1 and 2 are solvable relatively easily. createHistory
could allow registering callbacks for handling prompts. If any of these listeners return an unsuccessful value (as in there is unsaved work) a prompt would be displayed.
3 is a bit more tricky since the browser doesn't offer a way to block the URL change. Thus on cancel we'd have to navigate back to the page the user just left. This would have to be done before the router removes anything from the page so that no state is lost. This is what react-router does, I think.
Has any work in this area been done? I'll create an implementation if you don't see anything wrong with this approach.
Describe the bug
To Reproduce
<Router>
<main>
<Navbar />
<Route path="/" component={Queries} />
<Route path="queries" component={Queries} />
<Route path="statistics" component={Statistics} />
<Route path="status" component={Status} />
</main>
</Router>
<nav class="navbar navbar-expand-lg navbar-light bg-dark">
<a href="./" class="navbar-brand" use:link>
<h3>Analizator</h3>
</a>
<a class="nav-link" href="./queries" use:link> Poizvedbe </a>
<a class="nav-link" href="./statistics" use:link> Telefonija </a>
<a class="nav-link" href="./status" use:link> Stanje Arnes klicnih centrov</a>
</nav>
http://localhost:3000/ -> OK
http://localhost:3000/queries -> OK
http://localhost:3000/statistics -> OK
http://localhost:3000/status -> OK
https://sfinga2.arnes.si/analizator/ -> NOT OK
https://sfinga2.arnes.si/analizator/queries -> NOT OK
https://sfinga2.arnes.si/analizator/statistics -> NOT OK
https://sfinga2.arnes.si/analizator/status -> NOT OK
Expected behavior
working as in dev server on localhost
Desktop (please complete the following information):
Additional context Add any other context about the problem here.
Regards, TomaΕΎ
Is your feature request related to a problem? Please describe.
Describe the solution you'd like
<Router {basepath}>
<main>
<Navbar />
<Route path="" component={Queries} />
<Route path="queries" component={Queries} />
<Route path="statistics" component={Statistics} lazy="true"/>
<Route path="status" component={Status} lazy="true"/>
</main>
</Router>
I am getting these messages in the browser for a bunch of my Svelte components:
MainSidebar.svelte:18 was created with unknown prop 'location'
MainSidebar.svelte:18 was created with unknown prop 'navigate'
To avoid these messages, I have to define and export 2 variables/properties:
export let location // object with pathname: "/main/dashboard"
export let navigate
Do I have to do that for every single of my components? I didn't see any of this in the examples.
Describe the bug A clear and concise description of what the bug is.
useLocation()
hook throws error Function called oustide component initialization
.
To Reproduce Steps to reproduce the behavior:
useLocation()
Please add a link to an example in the Svelte REPL or in a Codesandbox, if you
can.
https://github.com/mataslib/uselocation-bug-repl
Expected behavior A clear and concise description of what you expected to
happen.
Show route content
Screenshots If applicable, add screenshots to help explain your problem.
Additional context Add any other context about the problem here.
Seems to not work only with Vite dev. It works with vite build, when u visit builded dist html. I used useLocation()
before with rollup and it was working. Then I switched to vite for its speed and it also did work. Today, I was removing and updating npm deps and it stopped working with this error. Unfortunately I wasn't able to revert to working state and detect the culprit, so I made this clean repl.
Describe the bug
See #3:
when navigating to a Route, that is not already rendered, the browser will check for a jump mark immediately, but of course rendering the Route takes some time, so the browser won't find the element and won't scroll the page.
I think there are two possible ways to solve this. Either, when calling
navigate
, e.g. by clicking aLink
, we need to update the Routers internal location first, wait for the Routes to render, and then callhistory.pushState
. But there is probably a lot of tricky work to be done. The second possibility is to assignwindow.location.href
back to itself, after all Routes have rendered. This however triggers apopstate
event in some browsers, which the Router will interpret as a new navigation, so we need to make sure, not to cause infinite loops by accident.
To Reproduce
... some content ...
<Route path="myRoute">
<main id="main">
Lorem ipsum dolor sit amet consectetur adipisicing elit.
</main>
</Route>
When opening /myRoute#main
, the page does not scroll to the main Element.
The same happens, when navigating to a Route
via a Link
or navigate
.
Expected behavior
The page should scroll to the element, referenced by the fragment.
To better automate the update and publishing, process a GitHub Action to run the tests on pushes and prs should be set up.
When you have a route with a path parameter you won't be able to navigate to the route if your path parameter value contains a dot.
Steps to reproduce the behavior:
Expected behavior
As the dot character is not a reserved sign it does not need to be URL encoded. I expect to be able to navigate to a route with a path parameter value containing a dot.
I have a need to refresh a section of the page which is a separate component with a dynamically generated list (paging). But it is not the main part of navigation and main menu only a subpage.
I've been sitting on this for 3 days (sic!) and can't figure it out.
I prepared some example image and code to present my problem:
Below is the simplified code, the real one is more complicated. Of course, this example not working
e.g. if I have a url like /login?next=/settings
, what's the proper way to access the value of "next"?
I couldn't quite figure this out from the README
V4 should make the router usable for more use cases. I've been planing on adding a hash based history for a while now. But there are a few things standing in the way to do this properly. Although the hash history would be optional, you'd still need the default browser history, as well as the fallback memory history module, even though you'd never use them. I've setup a new repo, where the history modules will be developed (svelte-navigator-history).
As a result the Router API will need to change slightly. There will need to be different Routers, like a HashRouter
and BrowserRouter
, similar to react-routers API. That's the only way to not bundle all history modules for every project.
In more detail, for v4 I'm planning to finish these tasks:
BrowserRouter
using the HTML5 History APIHashRouter
using the hash fragmentMemoryRouter
for testing and embedded widgetsAutoRouter
i want send params from my variable
example
<script>
let id = "myparams"
</script
<Link to="details/" **+ id** >details</Link> // id is my params -> localhost:3000/details/myparams
<Route path="details/id" component={Details}></Route>
my Details.Vue
<script>
import {useParams} from 'svelte-navigator'
let params = useParams()
</script>
detaiks aja {params.id}
Is there any way to disable the a11y functionality?
I went from svelte-routing to this one, because it felt like it was much more mature - but for some reason a focus rectangle popped up.
It took me a while to figure out that it was the a11y that set the tab index for the element to -1.
I don't need/want to have a11y for the page I'm trying to build and just wonder if there's any way to disable the functionality?
Describe the bug
actions.js:55 Uncaught TypeError: Cannot read property 'hasAttribute' of null
at actions.js:55
at HTMLDivElement.handleClick (actions.js:12)
svelte-navigator/src/actions.js
Line 55 in 6562b61
To Reproduce
Steps to reproduce the behaviour:
use:links
on the top level element<a>
elementSome CSS should be added to the examples, to show some basic techniques on how to style an app in an accessible way.
Focus outlines should be explained, as they are very relevant to the project (see #10).
Maybe Custom inputs, e.g. checkboxes, since they are very easy to make inaccessible.
Maybe add some more information and linked articles to the readme.
I have links that are generated in svg outside svelte but would like to use the routing instead of a page refresh
Its generated like so
const anchor = document.createElementNS("http://www.w3.org/2000/svg", "a")
anchor.setAttributeNS(null, "href", `${person.username}`)
I can't use use:link
for the <a>
as in svelte files.
Hi again, thank you for your support.
Hope you're doing well!
Today I was trying to implement a kind of accessibility features to my website.
I'm trying to do a a11y.createAnnouncement function based on the example you give in the README.md
When I add a meta object to a Route, this is not added to the component and when I print the information it is undefined.
Here you can see:
To Reproduce Steps to reproduce the behavior:
const createAnnouncement = (route, location) => {
const viewName = route.meta.name
const { pathname } = location
console.log(`Navegado a la vista de ${viewName} en ${pathname}`)
return `Navegado a la vista de ${viewName} en ${pathname}`
}
Expected behavior
route.meta.name is filled with the meta I pass to the Route component.
Desktop (please complete the following information):
Additional context
And a more question π
: What are the types of route and location in the parameters of the function? I'd love to know them to type them in my code since I'm working with TypeScript.
With TypeScript now being a first class citizen in Svelte, Svelte Navigator should provide typings.
I don't think it's possible at the moment to write everything in TS, because that would require any project using Svelte Navigator to have the TS pre-processor set up as well.
There would need to be a way to strip type annotations from Svelte components and produce regular Svelte components and declaration files from it.
So to get things started, declaration files should be enough.
Describe the bug
The screenshot below shows that join()
is being passed pathFragments
of null
and ""
respectively in paths.js
. This ultimately leads to a TypeError: str is null
in the stripSlashes()
function. I can see from the stack trace that $parentBase is the null value in question in Route.svelte
.
To Reproduce
Difficult, my codebase is a bit involved at this point. I have two <a>
elements on a navbar with use:link
attributes. Normally, they switch between pages/views perfectly.
One of my pages renders child component forms conditionally, based on some on:click
logic to mount/destroy the child components. These children in no way interact with routing. This error only occurs if any of the child components forms are loaded and I select the other <a>
on my navbar.
Desktop (please complete the following information):
Please let me know if you require any additional info, I'll try to put together a minimal example and reproduce in a REPL
Thanks for your work, I really enjoy using this library and the examples in the docs helped a lot.
I am trying to build a simple client-side svelte app with firebase (firestore and firebase auth) as a backend. I am getting a page with (This page cannot be found message) every time I try to do browser refresh/reload.
Currently, when navigating by clicking a Link, the link will remain focused after the transition is complete. This is a bad experience when using screen readers and other assistive technology.
The Router should move focus when navigating. It should:
Resources:
It looks like a Link
that routes to something on the same page does not actually work.
Link
component to all pages in your app, with in its to
something that refers to an anchor on a specific page, say /about#digital
, for instance <Link to="/about#digital"/>
Link
Page jumps to #digital on /about
In a tool I work on, we go around this by manually focusing the fragment and scrolling to it (running a function called honourFragmentIdLinks, onMount of a page).
This does the job, although it breaks if no navigation to a different page is happening (as that requires no mounting).
Describe the bug
I was looking at the private-routes example. Once you start the serve and navigate to http://localhost:<port>/profile
, it does not render the login page, event though the url changes to http://localhost:<port>/login
.
I moved code in PrivateRouteGaurd
to onMount
that appeared to work. But I am not sure if that is correct.
onMount(checkUser);
function checkUser() {
if (!$user) {
navigate("/login", {
state: { from: $location.pathname },
replace: true,
});
}
}
To Reproduce
Steps to reproduce the behavior:
http://localhost:<port>/profile
once you start private-routes
exampleWhen using renderWithRouter with jest + TypeScript the following error occurs:
TypeError: append_styles is not a function
at Object.init (node_modules/svelte/internal/index.js:1791:22)
at new Router (node_modules/svelte-navigator/dist/svelte-navigator.umd.js:1243:16)
at create_fragment (src/testHelp/WrapRouter.svelte:335:11)
at init (node_modules/svelte/internal/index.js:1809:37)
at new WrapRouter (src/testHelp/WrapRouter.svelte:452:3)
at render (node_modules/@testing-library/svelte/dist/pure.js:81:21)
at renderWithRouter (src/testHelp/renderWithRouter.ts:22:9)
at Object.<anonymous> (src/components/Layout.test.ts:5:19)
at TestScheduler.scheduleTests (node_modules/@jest/core/build/TestScheduler.js:333:13)
at runJest (node_modules/@jest/core/build/runJest.js:387:19)
at _run10000 (node_modules/@jest/core/build/cli/index.js:408:7)
at runCLI (node_modules/@jest/core/build/cli/index.js:261:3)
Here's a repo to reproduce the error.
Here's the error reproduced in GitHub Actions
No error and succesfully rendering the component with the wrapped router.
Upon route, focus is placed on the h1
. This is good. But when my route contains a hash
in its path, that breaks browser default behavior, which would be to scroll to relevant element and move the sequential focus starting point.
Steps to reproduce the behavior:
Focus of heading behavior is skipped, because the hash specifies a more specific location.
Heading is focused.
β¦
n/a
n/a
I have the following app:
//App.svelte
<script>
import { Route, Router } from 'svelte-navigator'
import Temp from './Temp.svelte'
</script>
<Router>
<Route path="/temp" component={Temp} />
</Router>
//Temp.svelte
<script>
import { useLocation } from 'svelte-navigator'
const location$ = useLocation()
$: console.log(JSON.stringify($location$))
</script>
After going to /temp
path (or refreshing) there are two identical messages in console:
{"pathname":"/temp","hash":"","search":"","state":null}
{"pathname":"/temp","hash":"","search":"","state":null}
Why is the reactive statement called twice if the location didn't change?
Is your feature request related to a problem? Please describe.
I need to test libs in edge 44
Describe the solution you'd like
a link to avoid having to set up my own example
Describe alternatives you've considered
my minimal example fails on edge 44 but im not sure if its due to svelte navigator
I'm trying to navigate from one page to another using useNavigate Hook and got the error which says - "Uncaught (in promise) TypeError: Cannot read properties of null (reading 'split')"
It should navigate to the page without that error.
Describe the bug
When pointing my browser to http://localhost:6062/profile
, the URL is properly redirected to http://localhost:6062/login
but the login form component is not displayed.
To Reproduce
Steps to reproduce the behavior:
cd svelte-navigator/example/private-routes
npm install
and npm start
http://localhost:6062/profile
in web browserExpected behavior
When you land on a private route the login form should be displayed.
Desktop (please complete the following information):
Hi. I'm using Svelte with Typescript. I'm using the Link component to navigate through my SPA.
I'm trying to write a class attribute to the Link component to stylize it but Typescript says it can't be.
Does exist any solution for it? I've read the whole documentation but I didn't found anything.
Thank you for your time.
Samuel,
Describe the bug A clear and concise description of what the bug is.
useLocation()
hook throws error Function called outside component initialization
.
To Reproduce Steps to reproduce the behavior:
useLocation()
Please add a link to an example in the Svelte REPL or in a Codesandbox, if you
can.
https://github.com/mataslib/uselocation-bug-repl
Expected behavior A clear and concise description of what you expected to
happen.
Show route content.
Screenshots If applicable, add screenshots to help explain your problem.
Additional context Add any other context about the problem here.
Seems to not work only with Vite dev. It works with vite build, when u visit builded dist html. I used useLocation()
before with rollup and it was working. Then I switched to vite for its speed and it also did work. Today, I was removing and updating npm deps and it stopped working with this error. Unfortunately I wasn't able to revert to working state and detect the culprit, so I made this clean repl.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.