Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Query String / Hash Support #77

Closed
bencompton opened this issue Jan 18, 2017 · 6 comments
Closed

Query String / Hash Support #77

bencompton opened this issue Jan 18, 2017 · 6 comments

Comments

@bencompton
Copy link

bencompton commented Jan 18, 2017

Does universal-router plan to support query strings and hashes? From my tests, it appears that these are not currently supported.

For example:

myapp/test?foo=1&bar=5#hash

Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.

@koistya
Copy link
Member

koistya commented Jan 18, 2017

Parsing hashes would work only on the client-side (in the browser). Are you using Universal Router in an isomorphic (universal) app or in regular single-page app (SPA)?

@bencompton
Copy link
Author

The short answer is SPA.

I'm actually evaluating it to potentially propose to the author of a Vue mobile web UI framework. It currently has its own router implementation designed primarily for SPAs, but with a router implementation that worked on the server, it could potentially support server rendering as well. The router implementation supports query strings and hashes, so I was curious about support for these features in universal-router.

@koistya
Copy link
Member

koistya commented Jan 18, 2017

@bencompton in the current version of the router, there is just a single UniversalRouter.resolve(routes, context) method. The second parameter can be customized to pass a query/hash strings as objects, for example:

import Router from 'universal-router';
import QueryString from 'query-string';
import routes from './routes';

Router.resolve(routes, {
  path: window.location.pathname,
  query: QueryString.parse(window.location.search),
  hash: QueryString.parse(window.location.hash),
}).then(render);

This approach ensures that you're using the exact same query string parsing library on the client and the server (which might be a big deal for isomorphic apps).

All this info is passed down to route handler functions, e.g.:

// some-route.js
export default {
  path: '/some-route',
  action({ path, query, hash }) {
    console.log(path, query, hash);
    // here you can check arguments passed via hash, e.g. /some-path#foo=123
    // validate and pass down to UI component(s), e.g. <MyComponent foo={hash.foo} />
    return ...;
  }
}

Do you think this will work for your use case, or you have a better idea how to support hashes?

@bencompton
Copy link
Author

@koistya thanks for the quick response! The current router accepts a string like /user/45/posts/28/?sort=first#opened and parses it. universal-router would be wrapped with the API of the current router implementation anyways, so it could certainly pre-parse the strings to separate the path from "other stuff" before passing it all onto universal-router for resolution.

So, universal-router should be perfectly usable as-is for this use case. In an ideal world, though, universal-router might support more generic syntax like this:

// some-route.js
export default {
  path: '/user/:userId/posts/:postId/?sort=:sortBy#:hash',
  action({ userId, postId, sortBy, hash }) {
    ...
    return ...;
  }
}

``

@frenzzy
Copy link
Member

frenzzy commented Jan 19, 2017

import Router from 'universal-router';
import queryString from 'query-string';

const routes = {
  path: '/user/:userId/posts/:postId',
  action({ path, params: { userId, postId }, query: { sort }, hash }) {
    console.log(path);   // => '/user/45/posts/28/'
    console.log(userId); // => '45'
    console.log(postId); // => '28'
    console.log(sort);   // => 'first'
    console.log(hash);   // => '#opened'
    return /*...*/;
  }
}

// location = '/user/45/posts/28/?sort=first#opened'
Router.resolve(routes, {
  path: location.pathname,
  query: queryString.parse(location.search),
  hash: location.hash,
}).then(render);

Playground: https://jsfiddle.net/frenzzy/1gk5mh1d/

@bencompton
Copy link
Author

@frenzzy, using the URL object looks like a really simple way to pre-parse a URL string and querystring is a nice, small library. That's perfect--thanks!

@frenzzy frenzzy mentioned this issue Mar 27, 2017
20 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants