🧭 Declarative, asynchronous routing for React.

Overview

Navi Logo

Navi

Declarative, asynchronous routing for React.

NPM Build

Navi is a JavaScript library for declaratively mapping URLs to asynchronous content.

It comes with:

  • A set of modern React components and hooks, with Suspense support
  • A static HTML generation tool that works with create-react-app without ejecting
  • Great TypeScript support

View the docs »

Quick Start

At it's core, Navi is just a router. You can use it with any React app – just add the navi and react-navi packages to your project:

npm install --save navi react-navi

If you'd like a more full featured starter, you can get started with Create React/Navi App:

npx create-react-navi-app my-app
cd my-app
npm start

Or if you want to create a blog, use create-react-blog:

npx create-react-blog react-blog
cd react-blog
npm start

Getting Started

For a full introduction, see the Getting Started guide on the Navi website.

Who's using Navi?

Contributing

We are grateful to the community for contributing bugfixes, documentation, translations, and any other improvements.

This repository is monorepo that holds the source for Navi and it's related packages, while the Navi website -- which includes Navi's documentation, is part of the navi-website repository.

Building and Testing Navi

To contribute code to Navi, you'll need to be able to build it and run the tests. To start, make sure you have lerna 3.x installed globally:

npm install -g lerna

Then fork, clone and bootstrap the repository:

lerna bootstrap
yarn build
yarn test

If you're working on Navi itself, it's often easier to run builds and tests from packages/navi

cd packages/navi
yarn test:watch

The examples are set up to use the copy of Navi at packages/navi/dist, so they can also be useful for quickly testing changes.

License

Navi is MIT licensed.

Comments
  • Slashes at end of URLs

    Slashes at end of URLs

    Is there a way to avoid the "/" characters getting added to my URLs?

    In this sandbox, click on the /page1 or /page2 links and you will see the URL change to /page1/ or /page2/. Happens in my own app, too.

    https://codesandbox.io/s/n7v5o7j310

    All the code:

    import React from "react";
    import ReactDOM from "react-dom";
    import { mount, route } from "navi";
    import { Router, Link } from "react-navi";
    
    import "./styles.css";
    
    const routes = mount({
      "/": route({
        view: () => (
          <p>
            Home. Go to <Link href="/page1">page 1</Link> or{" "}
            <Link href="/page2">page 2</Link>.
          </p>
        )
      }),
      "/page1": route({
        view: () => (
          <p>
            Page 1. Go <Link href="/">home</Link> or to{" "}
            <Link href="/page2">page 2</Link>.
          </p>
        )
      }),
      "/page2": route({
        view: () => (
          <p>
            Page 2. Go <Link href="/">home</Link> or to{" "}
            <Link href="/page1">page 1</Link>.
          </p>
        )
      })
    });
    
    function App() {
      return (
        <div className="App">
          <Router routes={routes} />
        </div>
      );
    }
    
    const rootElement = document.getElementById("root");
    ReactDOM.render(<App />, rootElement);
    
    help wanted 
    opened by jdiamond 14
  • crashing navigation.navigate call because _history undefined

    crashing navigation.navigate call because _history undefined

    Issue

    What happens is that i ask the user to load a url with a verification token in it. My [routeRegistry.login.verifyToken.path] should pick this up, and it does. It then loads the VerifyToken component in the bottom of this issue.

    But when everything goes fine, and it is suppose to call navigate, navigate crashes on this line https://github.com/frontarm/navi/blob/master/packages/navi/src/Navigation.ts#L182 It says _history is undefined.

    How come?

    Code setup

    I have this route setup for now

    export default mount({
      '*': map((request, context) => {
        const { authService } = context
        if(_.isEmpty(authService.currentUser)){
          const originalUrl = encodeURIComponent(request.originalUrl)
          return redirect(
            `${routeRegistry.login.path}?redirectTo=${originalUrl}`,
            {exact: false}
          )
        }
        return getAuthenticatedRoutes();
      }),
      [routeRegistry.root.path]: redirect(routeRegistry.login.path),
      [routeRegistry.login.path]: map(async (request, context) => {
        const { authService } = context
        if(!_.isEmpty(authService.currentUser)) {
          const path = decidedRedirectPath(request.params.redirectTo, routeRegistry.dashboard.path)
          return redirect(path)
        } else {
          return getLoginRoute();
        }
      }),
    })
    
    const getLoginRoute = () => {
      return mount({
        '/': route({
          title: 'Login',
          view: <SignUp />
        }),
        [routeRegistry.login.verifyToken.path]: route((req,context) => {
          const token = req.params.token
          return {
            title: 'Verifying...',
            view: <TokenVerification token={token} authService={context.authService} />,
          }
        }),
      })
    }
    

    With this verifyToken component

    import { useNavigation } from 'react-navi';
    
    export default ({token, authService}) => {
      let navigation = useNavigation();
      useEffect(() => {
        const verifyEmailAsync = async () => {
          const { res } = await verifyEmail(token);
          if(res.status === 200) {
            await authService.login(res.data.token)
            navigation.navigate('/dashboard');
          }
        }
        verifyEmailAsync();
      }, [])
    
      return (
        <div>Loading..</div>
      );
    
    opened by vongohren 13
  • Uncaught Error: URL not found

    Uncaught Error: URL not found

    First off, thanks for creating this! Super exciting project 🙌 Currently migrating a large web app from react-router to navi.

    It seems to be an Uncaught Error: URL not found when navigating to a page that doesn't exist. From the docs I believe the error is supposed to be a NotFoundError so that the <NavNotFoundBoundary /> but it just looks like a generic error based on the console output. The strange thing is that the Error boundary catches the error 🤔

    navi: 0.10.5 react-navi: 0.10.6 react: 16.6.0

    Because the error message is not present on my Express server (using createMemoryNavigation) it leads me to believe the problem might be related to createBrowserNavigation, but I'm uncertain.

    The error is also present on the examples on the Navi docs webpage 👇

    screenshot 2019-01-10 at 23 25 14
    Full stack trace
    Errors.js:24
    
    Uncaught Error: URL not found: /asdf/
        at createNotFoundSegment (Segments.js:38)
        at class_1../node_modules/navi/dist/es/Node.js.NodeMatcher.getResult (Node.js:29)
        at class_1../node_modules/navi/dist/es/Switch.js.SwitchMatcher.execute (Switch.js:121)
        at class_1../node_modules/navi/dist/es/Node.js.NodeMatcher.getResult (Node.js:22)
        at RouteObservable.refresh (RouteObservable.js:28)
        at RouteObservable.handleChange (RouteObservable.js:13)
        at RouteObservable../node_modules/navi/dist/es/RouteObservable.js.RouteObservable.subscribe (RouteObservable.js:51)
        at CurrentRouteObservable../node_modules/navi/dist/es/CurrentRouteObservable.js.CurrentRouteObservable.handleURLChange (CurrentRouteObservable.js:186)
        at CurrentRouteObservable../node_modules/navi/dist/es/CurrentRouteObservable.js.CurrentRouteObservable.refresh (CurrentRouteObservable.js:110)
        at new CurrentRouteObservable (CurrentRouteObservable.js:94)
    NaviError	@	Errors.js:24
    NotFoundError	@	Errors.js:40
    createNotFoundSegment	@	Segments.js:38
    ./node_modules/navi/dist/es/Node.js.NodeMatcher.getResult	@	Node.js:29
    ./node_modules/navi/dist/es/Switch.js.SwitchMatcher.execute	@	Switch.js:121
    ./node_modules/navi/dist/es/Node.js.NodeMatcher.getResult	@	Node.js:22
    RouteObservable.refresh	@	RouteObservable.js:28
    RouteObservable.handleChange	@	RouteObservable.js:13
    ./node_modules/navi/dist/es/RouteObservable.js.RouteObservable.subscribe	@	RouteObservable.js:51
    ./node_modules/navi/dist/es/CurrentRouteObservable.js.CurrentRouteObservable.handleURLChange	@	CurrentRouteObservable.js:186
    ./node_modules/navi/dist/es/CurrentRouteObservable.js.CurrentRouteObservable.refresh	@	CurrentRouteObservable.js:110
    CurrentRouteObservable	@	CurrentRouteObservable.js:94
    createCurrentRouteObservable	@	CurrentRouteObservable.js:53
    BrowserNavigation	@	BrowserNavigation.js:92
    createBrowserNavigation	@	BrowserNavigation.js:44
    main$	@	index.js:27
    tryCatch	@	runtime.js:65
    invoke	@	runtime.js:303
    prototype.(anonymous function)	@	runtime.js:117
    tryCatch	@	runtime.js:65
    invoke	@	runtime.js:155
    (anonymous)	@	runtime.js:202
    callInvokeWithMethodAndArg	@	runtime.js:201
    enqueue	@	runtime.js:224
    prototype.(anonymous function)	@	runtime.js:117
    ./node_modules/regenerator-runtime/runtime.js.runtime.async	@	runtime.js:248
    main	@	index.js:26
    ./src/index.js	@	index.js:72
    __webpack_require__	@	bootstrap:68
    0	@	commons.js:91567
    __webpack_require__	@	bootstrap:68
    (anonymous)	@	bootstrap:238
    (anonymous)	@	bootstrap:238
    Promise.then (async)		
    invoke	@	runtime.js:164
    (anonymous)	@	runtime.js:202
    callInvokeWithMethodAndArg	@	runtime.js:201
    enqueue	@	runtime.js:224
    prototype.(anonymous function)	@	runtime.js:117
    ./node_modules/regenerator-runtime/runtime.js.runtime.async	@	runtime.js:248
    main	@	index.js:26
    ./src/index.js	@	index.js:72
    __webpack_require__	@	bootstrap:68
    0	@	commons.js:91567
    __webpack_require__	@	bootstrap:68
    (anonymous)	@	bootstrap:238
    (anonymous)	@	bootstrap:238
    
    
    react-dom.development.js:15123
    
    The above error occurred in the <InnerNavContent> component:
        in InnerNavContent (created by Context.Consumer)
        in NavContent
        in InnerNotFoundBoundary (created by Context.Consumer)
        in ErrorBoundary (created by Root)
        in NavProvider (created by Root)
        in IntlProvider (created by LanguageProvider)
        in LanguageProvider (created by Root)
        in Provider (created by Root)
        in Root
    
    React will try to recreate this component tree from scratch using the error boundary you provided, InnerNotFoundBoundary.
    logCapturedError	@	react-dom.development.js:15123
    logError	@	react-dom.development.js:15157
    callback	@	react-dom.development.js:15931
    callCallback	@	react-dom.development.js:11194
    commitUpdateEffects	@	react-dom.development.js:11233
    commitUpdateQueue	@	react-dom.development.js:11224
    commitLifeCycles	@	react-dom.development.js:15271
    commitAllLifeCycles	@	react-dom.development.js:16523
    callCallback	@	react-dom.development.js:149
    invokeGuardedCallbackDev	@	react-dom.development.js:199
    invokeGuardedCallback	@	react-dom.development.js:256
    commitRoot	@	react-dom.development.js:16677
    completeRoot	@	react-dom.development.js:18069
    performWorkOnRoot	@	react-dom.development.js:17997
    performWork	@	react-dom.development.js:17901
    performSyncWork	@	react-dom.development.js:17873
    requestWork	@	react-dom.development.js:17761
    scheduleWork	@	react-dom.development.js:17566
    scheduleRootUpdate	@	react-dom.development.js:18240
    updateContainerAtExpirationTime	@	react-dom.development.js:18267
    updateContainer	@	react-dom.development.js:18324
    ./node_modules/react-dom/cjs/react-dom.development.js.ReactRoot.render	@	react-dom.development.js:18586
    (anonymous)	@	react-dom.development.js:18726
    unbatchedUpdates	@	react-dom.development.js:18124
    legacyRenderSubtreeIntoContainer	@	react-dom.development.js:18722
    render	@	react-dom.development.js:18783
    main$	@	index.js:64
    tryCatch	@	runtime.js:65
    invoke	@	runtime.js:303
    prototype.(anonymous function)	@	runtime.js:117
    tryCatch	@	runtime.js:65
    invoke	@	runtime.js:155
    (anonymous)	@	runtime.js:165
    Promise.then (async)		
    invoke	@	runtime.js:164
    (anonymous)	@	runtime.js:202
    callInvokeWithMethodAndArg	@	runtime.js:201
    enqueue	@	runtime.js:224
    prototype.(anonymous function)	@	runtime.js:117
    ./node_modules/regenerator-runtime/runtime.js.runtime.async	@	runtime.js:248
    main	@	index.js:26
    ./src/index.js	@	index.js:72
    __webpack_require__	@	bootstrap:68
    0	@	commons.js:91567
    __webpack_require__	@	bootstrap:68
    (anonymous)	@	bootstrap:238
    (anonymous)	@	bootstrap:238
    
    opened by rix1 13
  • '*' wildcard

    '*' wildcard

    I can't seem to find this in the docs, but is it possible to route with a '*' wildcard that acts as a middleware?

    Example:

    const routes = mount({
        '/login': route({
            view: <div>Login</div>,
        }),
        '/': redirect('/login'),
        '*': map((req, { user }) => (user ? protectedRoutes : redirect(req.originalUrl))),
    });
    
    opened by cevr 12
  • Errors importing as an ES module from unpkg

    Errors importing as an ES module from unpkg

    I have been trying to import navi directly from unpkg and have come across a few errors:

    1. If you request https://unpkg.com/[email protected]?module then this error appears:
    screen shot 2019-03-04 at 15 21 31

    Apparently this is related to webpack https://github.com/webpack/webpack/issues/8838

    1. If you specify the exact file https://unpkg.com/[email protected]/dist/es/index.js then the above error disappears but then this error appears:
    screen shot 2019-03-04 at 15 28 22

    Apparently this is to do with navi having history as an optional dependency (for interoperability with react-router). Solving this issue is likely to negate issue 1.

    opened by lukejacksonn 10
  • window.scroll with options object used in scrollToHash is not supported in IE, Edge, Safari and older versions of Chrome

    window.scroll with options object used in scrollToHash is not supported in IE, Edge, Safari and older versions of Chrome

    In scrollToHash function window.scroll method is called with options object. Unfortunately, this syntax is not supported by IE, Edge, Safari and older versions of Chrome (MDN docs), which only support the old syntax, i.e. window.scroll(x-coord, y-coord).

    Top 3 JS errors on our site reported by TrackJS are caused by this issue :/ Unfortunately some browsers that don't support it don't throw any error and simply scroll to 0, 0, but e.g. older versions of Chrome (e.g. 55, even though it should work according to MDN) throw the following error:

    Failed to execute 'scroll' on 'Window': No function was found that matched the signature provided.
    
    opened by szimek 9
  • Throw 404 error from the client side

    Throw 404 error from the client side

    Hi,

    Is it possible to throw a 404 error from the client side?

    I was trying something like this:

    throw new NotFoundError(request.originalUrl);
    

    But the NotFoundBoundary does not come up.

    opened by DB-Alex 7
  • Trying to access a sub route under an already mounted route does not trigger wildcard pattern

    Trying to access a sub route under an already mounted route does not trigger wildcard pattern

    I'm trying authenticated routes with permissions. I'm following a similar method explained in here: https://frontarm.com/navi/en/guides/authenticated-routes/#setting-authentication-state

    On wildcard stage, I use a method to authorize routes by comparing required permissions to access the route against permissions that the logged in user have to have more granular control over every route.

    export default mount({
      '*': map((request, context) => {
        const { authService, } = context;
        if(!authService.currentUser) {
          const originalUrl = encodeURIComponent(request.originalUrl);
          return redirect(
            `${routeRegistry.login.path}?redirectTo=${originalUrl}`,
            {exact: false,}
          )
        }
    
        const route = RouteAuthorizer(request, authService.currentUser);
        if (route) {
          return mount(route);
        }
      }),
      [routeRegistry.root.path]: redirect(routeRegistry.login.path),
      [routeRegistry.login.path]: mount(routes[routeRegistry.login.path].route),
    });
    

    I have all the routes listed and I use a separate method to authorize routes.

    // routes authorizer
    export default (req, userObj) => {
      const { path, } = req;
      const { route, permissions, } = Routes[path];
      if (permissions && permissions.length > 0) {
        if (!(userObj && isAuthorized(userObj.abilities, permissions))) {
          return null;
        }
      }
      return {
        [path]: route,
      };
    };
    
    // Routes registry
    export default {
    [routeRegistry.courses.path]: {
        permissions: routeRegistry.courses.permissions,
        route: route({
            title: 'Your courses',
            view: <Courses/>,
        }),
      },
      [routeRegistry.courses.courseDetail.path]: {
        permissions: routeRegistry.courses.courseDetail.permission,
        route: route({
          title: 'Specific course',
          view: <Course/>,
        }),
      },
      ...
    }
    

    The issue I'm facing is when I'm trying to navigate to a page while it's parent route is already being mounted.

    Ex: I'm trying to access courses/1 but courses/ is already mounted. So instead of going through the wildcard it jumps straight into courses/ route.

    Is there a way for me to force each path as unique?

    Or do you have a different pattern you use to achieve the same functionality?

    opened by maliiiith 7
  • How to use authenticated routes that are permission based?

    How to use authenticated routes that are permission based?

    I'm trying out Navi on a ReactJS application that has a bit complex routing system. What I'm doing right now is having a wildcard route, and then do necessary permissions checks and then mount routes based on the checks.

    '*': map((request, context) => {
        const { authService, } = context;
        if(_.isEmpty(authService.currentUser)){
          const originalUrl = encodeURIComponent(request.originalUrl);
          return redirect(
            `${routeRegistry.login.path}?redirectTo=${originalUrl}`,
            {exact: false,}
          )
        }
        if(!authService.currentUser.name) {
          return getLoginRoutes();
        }
        return getAuthenticatedRoutes();
      })
    
    const getAuthenticatedRoutes = () => {
      return mount({
        [routeRegistry.dashboard.path]: ...
      })
    };
    const getLoginRoutes = () => {
      return mount({
        '/': ...
      })
    };
    

    But with this approach I'm unable to unmount routes if the user loses permissions (when logging out).

    Do you have an example similar to what I'm trying to do right now?

    opened by maliiiith 7
  • Documentation - Authentication improvement proposal

    Documentation - Authentication improvement proposal

    At first let me tell you that I think you made a truly amazing job with this library, I prefer it to React router by far.

    While I was playing around I encountered the issue you are describing under the docs Delaying render until authentication section and while you explained one possible way to fix it, I thought I would share the one I found.

    I basically didn't like too much the idea of rendering the router before knowing the authentication state and felt like passing an isAuthenticationStateKnown prop to the context was a bit hacky as to me routes shouldn't be aware of the authentication state at all.

    Instead I came up with the following solution:

    export default function App() {
      // Custom hook that handles current user authentication state
      const [currentUser, setCurrentUser, authenticationStateIsUnknown] = useAuthentication()
    
      // Don't render anything until we know user authentication state
      // Could instead render a spinner or something indicating that the app is loading here
      if (authenticationStateIsUnknown) {
        return null
      }
    
      return (
        <Router routes={routes} context={{ currentUser, setCurrentUser }}>
          <Suspense fallback={null}>
            <View />
          </Suspense>
        </Router>
      )
    }
    

    As you can see, the useAuthentication() custom hook returns a authenticationStateIsUnknown boolean which we can use to determine whether to render the router or not.

    I won't share my custom hook code here as it is too business specific but its implementation is fairly trivial.

    Feel free to tell me what you think of this solution as I might be disregarding concerns that come along with it. I thought the docs should probably show a self-contained authentication example that doesn't require the routes to handle any transitional state.

    opened by pierreyves-lebrun 7
  • Cannot render redirection to async route from NavNotFoundErrorBoundary

    Cannot render redirection to async route from NavNotFoundErrorBoundary

    I have web app which instead of rendering "not found" page redirects to home page.

    Example code: https://frontarm.com/demoboard/?id=1f95147d-e713-4d80-a22a-af880c6810f2

    I'm trying to do it this way:

    function renderNotFound() {
      return (
        <NavHistory>{(history) => history.push('/about')}</NavHistory>
      )
    } 
    
    // [...]
    <NavNotFoundBoundary render={renderNotFound}>
      <NavContent />
    </NavNotFoundBoundary>
    

    and it works correctly when my page's getContent() returns content immediately, but when I try to redirect to async page

    '/about': Navi.createPage({
          title: 'The createSwitch() function',
          getContent: () => import('./about.mdx'),
        }),
    

    it fails with following errors in console:

    Uncaught Error: URL not found: /abc/
        at createNotFoundSegment (VM168 navi.js:322)
        at class_1.NodeMatcher.getResult (VM168 navi.js:363)
        at class_1.SwitchMatcher.execute (VM168 navi.js:872)
        at class_1.NodeMatcher.getResult (VM168 navi.js:356)
        at RouteObservable.refresh (VM168 navi.js:1336)
        at RouteObservable.handleChange (VM168 navi.js:1321)
        at RouteObservable.subscribe (VM168 navi.js:1359)
        at CurrentRouteObservable.handleURLChange (VM168 navi.js:1256)
        at CurrentRouteObservable.refresh (VM168 navi.js:1180)
        at new CurrentRouteObservable (VM168 navi.js:1164)
    The above error occurred in the <InnerNavContent> component:
        in InnerNavContent (created by Context.Consumer)
        in NavContent (created by Context.Consumer)
        in InnerNotFoundBoundary (created by Context.Consumer)
        in ErrorBoundary (created by Context.Consumer)
        in main (created by Context.Consumer)
        in div (created by Context.Consumer)
        in NavLoading (created by App)
        in Suspense (created by NavProvider)
        in NavProvider (created by App)
        in App
    
    React will try to recreate this component tree from scratch using the error boundary you provided, InnerNotFoundBoundary.
    
    Warning: Cannot update during an existing state transition (such as within `render`). Render methods should be a pure function of props and state.
    
    Uncaught Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.
        at invariant (VM167 react-dom.development.js:49)
        at scheduleWork (VM167 react-dom.development.js:18530)
        at Object.enqueueSetState (VM167 react-dom.development.js:12437)
        at NavProvider.Component.setState (VM166 react.development.js:460)
        at Object.NavProvider._this.handleNavigationSnapshot [as next] (VM173 react-navi.js:335)
        at MapObserver.next (VM168 navi.js:1963)
        at CurrentRouteObservable.handleURLChange (VM168 navi.js:1226)
        at VM168 navi.js:1163
        at listener (VM171 history.js:878)
        at VM171 history.js:897
    
    The above error occurred in the <Context.Consumer> component:
        in NavHistory (created by InnerNotFoundBoundary)
        in InnerNotFoundBoundary (created by Context.Consumer)
        in ErrorBoundary (created by Context.Consumer)
        in main (created by Context.Consumer)
        in div (created by Context.Consumer)
        in NavLoading (created by App)
        in Suspense (created by NavProvider)
        in NavProvider (created by App)
        in App
    
    Consider adding an error boundary to your tree to customize error handling behavior.
    Visit https://fb.me/react-error-boundaries to learn more about error boundaries.
    
    Uncaught (in promise) Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.
        at invariant (VM167 react-dom.development.js:49)
        at scheduleWork (VM167 react-dom.development.js:18530)
        at Object.enqueueSetState (VM167 react-dom.development.js:12437)
        at NavProvider.Component.setState (VM166 react.development.js:460)
        at Object.NavProvider._this.handleNavigationSnapshot [as next] (VM173 react-navi.js:335)
        at MapObserver.next (VM168 navi.js:1963)
        at CurrentRouteObservable.handleURLChange (VM168 navi.js:1226)
        at VM168 navi.js:1163
        at listener (VM171 history.js:878)
        at VM171 history.js:897
    
    opened by MBO 7
  • build failed on node >= 12

    build failed on node >= 12

    Find out more about deployment here:
    
      https://bit.ly/CRA-deploy
    
    navi-scripts: Using config at C:\Users\forge\Documents\GitHub\navi.config.js
    [ohshit] An error occured while building your app
    Couldn't find window.NaviScripts - did you call register()?
    Error: Couldn't find window.NaviScripts - did you call register()?
        at crawl (C:\Users\forge\Documents\GitHub\node_modules\navi-scripts\lib\crawl.js:22:15)
        at build (C:\Users\forge\Documents\GitHub\node_modules\navi-scripts\lib\build.js:9:32)
        at Command.<anonymous> (C:\Users\forge\Documents\GitHub\node_modules\navi-scripts\bin\navi-scripts.js:89:7)
    error Command failed with exit code 1.
    info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
    

    I don't know why this is not resolved yet and no one is following up, but I want to bring this issue to the light again:

    To reproduce this error just use any node version >= 12 and this error will encounter during the build phase.

    Related to: https://github.com/frontarm/navi/issues/92 https://github.com/frontarm/navi/issues/83

    opened by weihao 1
  • Preserve scroll position when going back/forward

    Preserve scroll position when going back/forward

    Similar to #190.

    When using the traditional forward/back buttons, the scroll position is preserved. If you scroll down, click a link, and then go back, you won't end up back at the top of the page.

    Because it emulates the forward/back buttons, Navi should also preserve scroll position when going forward and back.

    opened by JacksonGariety 1
  • Error in Typescript blog example

    Error in Typescript blog example

    Hi, I was trying out the Navi TS blog example and as soon as I ran yarn start I got this:

    navi/my-blog/node_modules/@types/react-dom/node_modules/@types/react/index.d.ts
    TypeScript error in /Users/erick/Documents/spark-analytics/navi/my-blog/node_modules/@types/react-dom/node_modules/@types/react/index.d.ts(2978,14):
    Duplicate identifier 'LibraryManagedAttributes'.  TS2300
    
        2976 |         // We can't recurse forever because 'type' can't be self-referential;
        2977 |         // let's assume it's reasonable to do a single React.lazy() around a single React.memo() / vice-versa
      > 2978 |         type LibraryManagedAttributes<C, P> = C extends React.MemoExoticComponent<infer T> | React.LazyExoticComponent<infer T>
             |              ^
        2979 |             ? T extends React.MemoExoticComponent<infer U> | React.LazyExoticComponent<infer U>
        2980 |                 ? ReactManagedAttributes<U, P>
        2981 |                 : ReactManagedAttributes<T, P>
    

    Any idea why?

    Cheers!

    opened by ericklind 0
  • Decode

    Decode "+" in query string

    The plus-character is not getting decoded when used in the query string, but is instead passed on as-is in query parameters in request.params.

    An example of a query string that uses plus signs is the default Github issues search query: https://github.com/frontarm/navi/issues?q=is%3Aissue+is%3Aopen+

    See:

    • https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL
    • https://stackoverflow.com/questions/18717557/remove-plus-sign-in-url-query-string
    opened by malthejorgensen 0
Declarative routing for React

React Router Declarative routing for React Docs View the docs here Migrating from 2.x/3.x? 3.x docs 2.x docs Packages This repository is a monorepo th

React Training 49.2k Dec 27, 2022
Declarative routing for React

Welcome to React Router · React Router is a lightweight, fully-featured routing library for the React JavaScript library. React Router runs everywhere

Remix 49.3k Jan 9, 2023
reach - Next Generation Routing for React

Next Generation Routing for React Documentation Documentation Site You can also find the docs in the website directory. Community Join us on Spectrum

Reach 6.9k Jan 7, 2023
🥢 A minimalist-friendly ~1.3KB routing for React and Preact. Nothing else but HOOKS.

wouter is a tiny router for modern React and Preact apps that relies on Hooks. A router you wanted so bad in your project! Features Zero dependency, o

Alexey Taktarov 4.8k Jan 4, 2023
VSCode extension to generate a router based on file based routing and nested layouts

vscode-router-generator VSCode Extension to generate a router based on a file structure and returning the correct nested layouts. There can be optiona

Rody Davis 8 Sep 29, 2022
Declarative router component for React.

React Router Component Version Compatibility >= 0.39.0 React v15,16 >= 0.32.0 React v15 >= 0.27.0 React 0.14 0.24 - 0.26.0 React 0.13 0.23 - 0.26.0 Re

Samuel Reed 871 Nov 29, 2022
Render isomorphic React + React Router apps and components in Node

Render isomorphic React + React Router apps and components in Node

Sequence Media 3 Nov 1, 2022
named routes for react-router and your react application

react-router-namesake Example import { Switch } from "react-router"; import { BrowserRouter, Route, Link } from "react-router-dom"; import { Router as

Joe Hsu 6 Aug 12, 2021
Frontend of agro rent app built with React, Axios, React-router-dom v6 & Bootstrap

Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: ya

Anuj Sharma 1 Dec 8, 2021
React app with TypeScript - React Router Dom

React Project with - React Router Dom My name is Alex Principe. I'm a Full stack developer who shares programming code with the community. This repo c

Alex Principe 2 Sep 20, 2022
You can found the concept of react hooks, local storage, conditional rendering and react-router-dom.

Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: np

Tikaram Acharya 2 Jun 1, 2022
Upschool-react-assignment - Dummy Amazon clone with Bootstrap and React

Dummy Amazon Clone with React - NozamA ?? In this assignment, I tried to build a

Merve Karabulut 12 May 13, 2022
a more intuitive way of defining private, public and common routes for react applications using react-router-dom v6

auth-react-router is a wrapper over react-router-dom v6 that provides a simple API for configuring public, private and common routes (React suspense r

Pasecinic Nichita 12 Dec 3, 2022
Automatic breadcrumbs for React-Router

React Breadcrumbs React component use to generate a breadcrumb trail (compatible with React Router). Installation npm install --save react-breadcrumbs

Sven Anders Robbestad 409 Dec 9, 2022
React Router scroll management

react-router-scroll React Router scroll management. react-router-scroll is a React Router middleware that adds scroll management using scroll-behavior

Jimmy Jia 846 Dec 18, 2022
:tada: Redux First History - Redux history binding support react-router - @reach/router - wouter

redux-first-history Redux First History - Make Redux 100% SINGLE-AND-ONLY source of truth! Redux history binding for react-router @reach/router wouter

Salvatore Ravidà 367 Dec 31, 2022
Redux bindings for React Router – keep your router state inside your Redux store

redux-router This project is experimental. For bindings for React Router 1.x see here In most cases, you don’t need any library to bridge Redux and Re

Andrew Clark 2.3k Dec 7, 2022
🔼 UI-Router for React

UI-Router provides extremely flexible, state based routing to the React ecosystem.

UI-Router 444 Dec 22, 2022
Easy Router for Effector with React bindings

effector-easy-router A declarative router for effector and react. It is inspired by react-router-dom and effector gates. Routes are independent from e

Kirill Kubryakov 10 Oct 7, 2022