krasimir / navigo Goto Github PK
View Code? Open in Web Editor NEWA simple vanilla JavaScript router.
License: MIT License
A simple vanilla JavaScript router.
License: MIT License
It took me while to figure out how to use one parameter as the url. My root url is http://localhost:43088/test-page
router.on(':slug', function (slug) {
// slug is "http:"
});
When the parameter is not the first thing, it works like it should:
http://localhost:43088/example/test-page
router.on('/example/:slug', function (slug) {
// slug is "test-page"
});
This can be fixed with a custom regex /([\w-]+)$/
(Anything [a-zA-Z_-] at least once untill the end of the string)
A better solution would be to exclude the root from the matching process.
I'm probably just a noob but I dropped in navigo.min.js and Navigo just isn't being found. Both:
var router = new Navigo(root = null, useHash=false);
and
var router = new Navigo();
Is there another component like RequireJS that I'm missing here?
Is support for hooks and named routes possible?
router.on(
'/':
as: 'home'
uses: (params, query) ->
console.log 'Router: Home Route...'
renderHome()
hooks:
before: ->
console.log 'BEFORE'
after: ->
console.log 'AFTER'
)
Is there a way to specify a callback function through Navigo any time the route changes?
Like the simplicity of your router, but it would be nice to have a simple click handler to intercept <a href='/route'>
clicks. Is that on the roadmap?
Can you add changelog, please? It doesn't clear what changed in newer versions and should I upgrade.
Browser history is helpful but would be better if there were optional custom titles for each route. This would be a lightweight feature add-on but something very useful built-in to the router. Currently I change it in the route handler. Since navigo is already handling history state, this might be something useful for others. Is this something anyone else is interested in? I'd be willing to make the changes if we could agree on a reasonable syntax.
Hello,
Thank you for Navigo. Forgive me if this is by design, but I noticed that changing just the querystring of a route and calling navigate does not resolve. I think this is a side effect from removeGETParameters that was introduced a few weeks ago. Is this a bug and if not, is there a workaround?
Thanks
Looking for a way to fire different functions on a given route, but only depending on which route was last visited. Is there already a way to do this?
You replace hrefs with javascript:void(0);
although e.preventDefault()
is used.
Is there a reason for doing so?
More of a feature request than an issue here.
You trigger routes although you're already there. I tried to circumvent by detecting if the triggered route is already the actual page, problem though, by the time I check for it the triggered route is already added to the history, which kinda breaks the browser's back button.
My original code just extracted any query parameters from the last params
property that was resolved. I honestly thought that this was how it was designed to work... but w/e.
Since b1d7a98#diff-1fdf421c05c1140f6d71444ea2b27638R95 query parameters are now completely lost (they're just stripped).
If Navigo is going to interfere with query parameters now, it should instead pass an additional parameter to the callback with the string it removed so applications that relied on it can upgrade, e.g.
router
.on('/user/:id/:action', function (params, query) {
// ......................................^
})
Hi @krasimir - thanks for your work Navigo, really liking it so far.
I have encountered one issue that I wanted to raise , and that is that all routes seem to be greedy. Meaning that, given a route of /foo
, the findMatchedRoutes
function will return a positive match for the path /foo/bar
, regardless of whether or not a wildcard is used. I believe this RegExp is to blame: https://github.com/krasimir/navigo/blob/master/src/index.js#L5.
Was this an intentional design decision? If not, I am happy to open a PR to fix this issue. Regardless, probably should add a spec to cover this case.
Currently the regex for the parameters is like this:
var PARAMETER_REGEXP = /([:*])(\w+)/g;
Could we possibly change it to this? (adding "-" to the possible matches allowing for the use of GUIDs as routing parameters)
var PARAMETER_REGEXP = /([:*])([a-zA-Z0-9-]+)/g;
Hi there, great work! How can I achieve that, when I navigate to an url using router.navigate('/products/list/');
, the trailing slash stays in the route? I would need this to have consistent urls, both from the server as well as from the js app.
If I have the URL https://mysite.com/page#
, and a route defined as /:id
, then params.id
is page#
. Should it just be page
? I.e. the #
should not be considered part of the param?
I'm running into this issue because Chrome automatically appends #
to my URL after redirecting from another page that has #
in its URL
let router = new Navigo(null, false);
router
.on('#/home', controllers.home)
.on(() => {
router.navigate("#/home");
})
.resolve();
When the path in the browser is empty I get the following error
Uncaught (in promise) Error: (SystemJS) router is not defined(…)
Do you have any ideas why, the module is loaded with systemjs
In JSBin example the navigo.js lib points to http://work.krasimirtsonev.com/git/navigo/navigo.js and may be your htaccess redirect the url.
Just can swich it to http://krasimir.github.io/navigo/lib/navigo.js
I have this:
router.on('/pub/:pub', function (params) {
console.log("route 2");
gotoPageTwo(params.pub);
});
router.on('/', function (params) {
gotoPageOne();
});
When I am on "route 2" page and refresh, the route then fires twice.
Any ideas?
Hello,
Is it possible to latch onto the window.onpopstate
event Navigo uses for forward/back buttons? I can use it easily enough, but then navigo stops working :)
I have a page transition in this project, so it's not possible to re-render the menu in this case. I'm manually updating the .active
class on the menu with jQuery, which works fine, except for the forward/back browser buttons.
Was thinking a custom event could be fired onpopstate with the window.location.pathname
passed to it, but interested in your thoughts.
Thanks.
Hey guys,
Not a bug but rather an idea. I was thinking about adding hooks to this router and was wondering what you think. With hooks you could have page transitions or initialize page specific libraries and things like that.
I imagine they could be called like this:
//global hooks that run before and after all routes`
Router.beforeRun(function () {
//do stuff
});
Router.afterRun(function () {
//do stuff
});
Router.beforeLeave(function () {
//do stuff
});
Router.afterLeave(function () {
//do stuff
});
//route specific hooks
Router.beforeRun('myAwesomeRoute', function () {
//do stuff
});
///etc...
Thoughts @krasimir? If you're open to the idea, we can talk design and then I can submit a draft. Let me know.
Thanks,
Daniel.
Hey
I love this router and have used it on a lot of small projects with no issues, thanks! I'm now scoping a larger project, and there's one thing stopping me from using it there (well two related things).
Some example routes:
const trip = new TripController();
router.on({
'/trip/:tripId/edit': trip.edit,
'/trip/create': trip.create,
'/trip/:tripId': trip.show,
'/trip': trip.index
});
An example for a named route API (using Laravel 5.2 API as inspiration):
const trip = new TripController();
router.on({
'/trip/:tripId/edit': {as: 'trip.edit', uses: trip.edit},
'/trip/create': {as: 'trip.create', uses: trip.create},
'/trip/:tripId': {as: 'trip.show', uses: trip.show},
'/trip': {as: 'trip.index', uses: trip.index}
});
Then using the custom names, we don't need to hardcode URLs in th views:
<a href="{{ router.generate('trip.show', {tripId: 6}) }}">...</a>
Single routing paths work perfectly, such as: http://domain/classes
Whenever I try to 'stack' routes or just add a single forward slash '/' after the route I get this error, such as http://domain/classes/ or http://domain/classes/students
I'm just building a simple example testing if navigo is something that would work for me. Followed the examples, built a very simple html5 ( valid testing cleared ) page.
Any ideas would be appreciated!
I'm using Navigo with dynamic links - I have a simple href link with data-navigo
attribute. When I click it, everything works out well, I get new data from the server.
But then I update the href attribute, using something like:
$('#link').attr('href', '/new/value');
Unfortunately this does not work properly. I first tried calling updatePageLinks
, which is not documented but it's available as a function. It kind of works, but it attaches a lot of listeners to the very same link, because old ones are not cleared. I guess it just fires up a lot of redirects and I end up on the right one, I don't know (didn't investigate it too much).
I think the location property should be checked inside the click listener, instead before that:
updatePageLinks: function updatePageLinks() {
var _this = this;
if (typeof document === 'undefined') return;
this._findLinks().forEach(function (link) {
var location = link.getAttribute('href'); // do NOT use this one, as it's set only once
link.addEventListener('click', function (e) {
if (!_this._destroyed) {
e.preventDefault();
//_this.navigate(clean(location)); // don't use pre-saved location
// get one each time the link is clicked
// it's slower, but more robust and works for dynamic href changes
// I found out that pathname is the actual href
// as href gets transformed to the real address
// ex: href="/test" -> e.currentTarget.href = "www.example.com/test"
_this.navigate(clean(e.currentTarget.pathname));
}
});
});
}
I can make PR if you find this helpful :)
When using the demo site everything works as expected using the history api. But when you click the "hashed based routing" box in the upper right (and even after refresh) you get
http://work.krasimirtsonev.com/git/navigo/#about
http://work.krasimirtsonev.com/git/navigo/#usage
http://work.krasimirtsonev.com/git/navigo/#download
ok
but then
http://work.krasimirtsonev.com/git/navigo/testing (quickly replaces #test)
and from then on the hash is after /testing
http://work.krasimirtsonev.com/git/navigo/testing#download
http://work.krasimirtsonev.com/git/navigo/testing#usage
That doesn't seem right.
When binding an event to links at start it will not catch clicks on links which are loaded later. For example if I load a new template with links, router will not change the url properly.
I think it would be better to bind event to document:
$(document).bind('click', '[data-navigo]', function() {
// do stuff
}
@krasimir maybe it's time to use onhashchange event instead of setTimeout for resolving the hash state, but keep last one in the code as a fallback?
Browser support https://developer.mozilla.org/ru/docs/Web/API/WindowEventHandlers/onhashchange
Example:
router.on('/', function(){ console.log('home') }
router.on('/about', function(){ console.log('about') }
router.on('/contacts', function(){ console.log('contacts') }
On init will log 3 times 'home'
It seems to me that if you have something like
Router.on('/foo/:foo/bar/:bar', (params) => {console.log(params)}.resolve();
And you navigate to /foo/4/bar/5?a=c
params.bar will equal "5?a=c" as opposed to just 5.
Hi there, it's me again. Is there a way to sart the router silently? Like, without fireing the first route?
Hi, I wanted to let you know the official page doesn't show any content beside the tabs navigation..
I'm on Firefox 50, Windows 7
Hi there,
I just stumbled upon this lightweight router library and I'm pretty delighted of how it works. There's only one problem I'm having:
If the browser does not support pushState
, the library falls back of using hashes as links. I think it would be nice to have the option to disable that at all, because in most cases that means doubling the logic for routing (especially in backend) - with and without hashes.
I also don't like the idea of my old browser checking five times a second what's the url (I mean I really won't need that, not that it's bad as an idea).
I don't know what's the best scenario for doing it - provide another parameter, add public method, I don't know. But I think it would be pretty nice if it can work.
Поздрави :)
For example, there is an older and smaller in size vanilla router page.js.
What whas the main reason you created another router?
Have you analyzed how Navigo is different/better/worse then other router libraries?
Nevertheless, nice work and your ES6 syntax and export is very appreciated in my build process.
Thanks for this library. I am able to get hash based routes working but cannot get clean URLs to work on my localhost. I added the Apache .htaccess routing as described in http://krasimirtsonev.com/blog/article/deep-dive-into-client-side-routing-navigo-pushstate-hash but does not seem to work.
Also tried setting the "root" value when creating a new Navigo() instance but not sure what that argument should actually look like, i.e. http://localhost, localhost/index.html, etc
Hi. I'd like to make a suggestion about the feature.
Following steps are for an imagination of workflow.
There's a version number in package.json
, but Bower looks for git version tags in the repository, so specifying a version to install with Bower isn't working. Could you push version tags to the repo?
The bug is reproducing here with Navigo 2.3.0:
https://jsbin.com/ximekug/edit?html,js,output — source code
https://output.jsbin.com/ximekug/ — there you can see URL changing
With each click text under the list should change according to link.
Steps to reproduce:
URL changed, but text under the list didn't.
Also can be reproduced this way:
If we click “Task 1” → “Home” → “Task 2” → “Home” → “Task 1” → ... It works as expected.
Hey, thanks for the awesome library :)
Do you have plans to implement support for the state object param of History.pushState()
?
My current use case is to save scroll position between pages. The site I'm working on is fully AJAXed so I can persist a variable with the scroll position between page transitions. But, if a user reloads the page, the previous scroll position is lost. So then if they hit the back button, the page scrolls back to the top regardless of where they were previously.
Seems like the cleanest way to do it would be to just push a state object along with the route to router.navigate(path = '', state = {}, absolute = false)
. I'm happy to open a PR if you like this idea, or defer to you if you already have this feature in the works.
Hey, I'm having a problem with Navigo.
I have this url:
http://localhost:3000/users/foo#section1
In this page I have some tabs (section1, section0) when I click any of the tabs and the url changes to, for instance, http://localhost:3000/users/foo#section1
Navigo triggers the resolve even with the hash navigation disabled.
Is there a way to replace the current state, instead of just push via navigate()?
For changing language I'm looking for such functionality, since changing language is not really navigating away from the current content.
Instead of having to .pause
the router before .navigate
in order to skip resolving, can the resolve/ paused state be passed in as a boolean to .navigate()
?
For eg., instead of having to do
router.navigate('/path');
router.pause(false);
It will just be
router.navigate('/path', false);
I find the .pause(false)
API to be extremely awkward.
Another issue I found is the use of relative paths vs. absolute paths.
You declare links in data-navigo attributed links with relative paths (eg. "about"). The router declares "/about" though. Somehow the link still trigger the particular route, but end up in doubled slashes in the address bar (eg. somedomain.com//about).
Hey, first of all thank you for this simplistic but very helpful router :)
I've got a problem where updatePageLinks doesn't work as intended in the minified version. It somehow adds multiple (in my case even different) click handlers to an element with data-navigo attribute. I think it is because in the minified file link.hasListenerAttached isn't set to true correctly. The different click handlers could be because I'm exchanging the href attribute though...
In the non-minified version everything works fine though
Hi,
First, Thankyou for the simple router. Made my life easy.
I am not reporting a bug but need some help here. This should have been very simple but I am not able to figure out how to differentiate between no query and an unmatched query. I have written a fallback so:
router.on({
'p1' : loadP1,
'p2' : loadP2,
'g1' : loadG1,
's1' : loadS1,
'user' : loadUserPage,
'#': loadLanding
}).resolve();
router.on(function fallback() {
alert('oops!! this page was not found');
}).resolve();
but this get fired even for my landing index.html without any queries at all. I want to fire the fallback for unmatched queries only. I am using hash.
Hi,
I have a problem when I used your lib. when I need to set path more then one i got error message in console like this
bundle.js:1 Uncaught SyntaxError: Unexpected token <
this is my code
const Navigo = require('navigo');
var router = new Navigo();
router.on({
'path/to/some/where' : () => {
console.log('path/to/some/where');
},
'/' : () => {
console.log('Home');
},
});
router.resolve();
this is .htaccess
<ifModule mod_rewrite.c>
Options +FollowSymLinks
IndexIgnore */*
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) index.html
</ifModule>
localhost
page ware working fine BUT localhost/path/to/some/where
got error I told you above.
I am having trouble with the following code : When I type the following url '/v1/a/b/c', I'd like to match the "not found" handler. Instead, I match the root path that I defined at last ('/'). It's like I would have defined it that way : '/*'.
var router = new Navigo('/v1');
router.on('modify', function () {
setContent('modify');
})
.on('modify/:name', function (params, query) {
setContent('name');
})
.on('/', function () {
setContent('home');
})
router.notFound(function () {
console.log("not found");
// called when there is path specified but
// there is no route matching
});
router.resolve();
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.