I have private pages behind a login page, if you try to reach a page the first you'll face is a redirect to the Login page and once you're logged successfully you will be redirected to the page you ask for, for example.
https://example.com/one-of-the-private-pages
redirect to
https://example.com/login
then redirect to
https://example.com/one-of-the-private-pages
the redirect is with the navigate utils from Gatsby
All this Logic is working as expected but the problem is when I need query parameters
https://example.com/one-of-the-private-pages?param1='example'
In this case, the behavior is:
Redirect to the Login page
After login
navigate(https://example.com/one-of-the-private-pages?param1='example')
then I can see a blink in the page with the parameter and a hard refresh
Finally, my URL is:
https://example.com/one-of-the-private-pages
This only happens after building to production in development mode everything works as respected
Note: I try deleting all the content on the page actually only has a div and an h1 component.
Gatsby, extends from #reach/router (from React) so it follows the behavior of it. It's intended to use only for internal navigation and, by default, does not support hashed URLs nor parameters, as the docs points:
Neither <Link> nor navigate can be used for in-route navigation with a
hash or query parameter. If you need this behavior, you should either
use an anchor tag or import the #reach/router package—which Gatsby
already depends upon—to make use of its navigate function, like so:
That's why your page blinks before losing the parameters. Don't focus on the gatsby develop/gatsby build, they have different behaviors, treat and compile the code differently and, that doesn't mean that your code has something wrong and it has stopped working in one environment, it's just that Gatsby doesn't support it.
Said that, at this point, you have two options:
Use the #reach/router dependency directly, as the documentation suggests:
import { navigate } from '#reach/router';
...
onClick = () => {
navigate('#some-link');
// OR
navigate('?foo=bar');
}
Note the import { navigate } from '#reach/router'; (not from Gatsby)
Using window.location redirection to get the parameters (manipulate them as you wish) and redirect the user accordingly.
Additionally, try using partial routes instead of absolute ones, since the internal navigation works better in that scenario, like:
navigate(/one-of-the-private-pages?param1='example')
I just solve my problem, I was using the full URL to navigate
Wrong:
navigate(https://example.com/one-of-the-private-pages?param1='example')
Correct:
navigate(/one-of-the-private-pages?param1='example')
Related
I have made a back button for my isomorphic react application and am accessing the current URL of the page to check if my user is coming from the inside my application entry point or directly entering the URL for the subpage of my application into the browser. The thing is that if someone has hit my subpage URL directly then I redirect them to a default page otherwise I allow goBack functionality provided by withRouter HOC from React.
my code to handle Back button functionality looks like this
if(this.props.location===reactReferer.referer()){
this.props.history.push('/about')
else { this.props.history.goBack(); }}
what am I doing wrong as this doesn't seem to be working? I imported the following package and npm installed it 'react-referer'
I have a menu with links to different pages, but when I click on the link to the page I'm already on, literally nothing happens. I want the page to rerender as if the user clicked in from another page.
I've tried
navigate('/temp')
navigate(link, { replace: true })
but it's not working.
The short answer is that you can't refresh the same page using #reach/router (from React, and Gatsby extends from it). This is because the location is the same so for the internal routing, nothing changes hence the refresh is not forced.
The easiest way to achieve it is by using the old-fashioned window.location.reload(). This will refresh the full page, forcing the components to be rendered again.
You can follow this GitHub thread for further information. As you can see, it can be achieved by diving into history.pushState and in other tricky ways but it always ends in a headache, it's not recommended since it's not the purpose of the #reach/router if it thrives will be with multiple caveats.
For standard internal navigation between pages, use <Link> component rather than navigate.
While I was using Link in React Router and history.push method,
I realized I have used those two method without proper knowledge.
I have used Link tag makes user possible to go to another component, and used history.push to make back button available.
But hard to tell the difference except history method stacks a trace.
What is the difference between Link and history.push besides I have mentioned above and how to use them properly?
With the Link you can navigate to another "page" by wrapping it for example a button and do the redirect when clicking. Mostly this is what you probably want to do.
But in some cases you want to navigate to another "page" programatically. For example when something changes in your app that has nothing to do with clicking on a button or link.
So you can use history.push to change the url programmatically without the need to click on a button or a link.
I hope this clears it for you
I am trying to learn react router 4 but meet some problems. I follow the guide from here https://reacttraining.com/react-router/web/example/no-match, and yes this example works fine in my browser. I can click the links and get things shown in the browser.
but, if I type in the url in the browser instead of click the links, the page shows NOT FOUND
NOT FOUND page
What's happening? Does React-router can only use links instead of typing in URL??
Stijn de Witt explain about this "problem" here: https://stackoverflow.com/a/36623117/8272354
When you initialize with the URL in the "inital route" of your route system, all the routes "know" how to deal with Router Links. So, the React Link does't refresh the browser, just change the route internally in javascript and load the specifyc route. This way everything works fine.
But, when you type the route (not the "initial route") directly in the URL, the router system does't understand that route, and the browser will try get this page in the server.
Any quick-and-easy answer to the scenario where you want to build something like a simple questionnaire with React and React Router where you don't want the user to be able to modify the URL to browse anywhere and you also don't want to push history state into the browser, essentially preventing use of the back button?
Sample routes might look like:
questions/1
questions/2
questions/3
...so on
But the URL should stay the same at all times and the history won't change, essentially what a single page app without routing would behave like.
For the history part, you would need to use replaceWith() everywhere you want to change route.
If you're using <Link>, you could create your own version which uses replaceWith instead of transitionTo - you should just be able to copy its implementation and replace the PropTypes require call with require('react-router/lib/PropTypes').
I can't immediately think of a non-horrible way to prevent the user from jumping around though - presumably you also want the app to break if they try to start on anything but the base URL? I would just use some simple state to control which component is currently being rendered instead of using React Router if that's the behaviour you really want.