Dynamic route not working on page refresh with Next.js - reactjs

I'm used Next.js but i have an error with dynamic route.
In my application I use getStaticPaths, getStaticProps and this:
<Link
href={`/offers/[id]?id=${offer.id}`}
as={`/offers/${offer.id}`}
>
<a>{offer.title}</a>
</Link>
When I click on this link, I have no problem with the dynamic route to display my page.
But when I refresh the same page, I get this message:
When I looked for a solution the answer was that my Link did not have the right setting when clicked on.
But now I don't click on the link, I just refresh my page.
I use Next.js 10.0.7

Since Next.js 9.5.3 there's no longer the need to use as for dynamic routes. Instead you can directly use the value to interpolate in href.
<Link href={`/offers/${offer.id}`}>
<a>{offer.title}</a>
</Link>
Alternatively, you can also use a different Link syntax by passing a URL object to it.
<Link
href={{
pathname: '/offers/[id]',
query: { id: offer.id }
}}
>
<a>{offer.title}</a>
</Link>

I had a similar problem. But I've been working with translations on the website.
So when I change selected language on any page it works fine, but as soon as I change language on any of the [id] page (item, article, etc.) I got the same error as you have.
In my case the problem was inside router.push() method I've used.
So when I pass router.pathname it returns /articles/[id] literally.
But actually I needed to use router.asPath which returns the correct URL path, such as /articles/abc123-456zczxc-7890-blablabla.
Here is an example from NextJS docs:
pathname: String - Current route. That is the path of the page in /pages, the configured basePath or locale is not included.
asPath: String - The path (including the query) shown in the browser without the configured basePath or locale.
NextJS API Reference Link

Related

How add ability add query params for gatsby routes?

How to generate pages in gatsby that will allow you to add parameters to the routing like https://page1?someParam=param or https://page1/param
What I mean? When we navigate to page page1 in gatsby it work's fine, but what if I just want add uniq params for page for google analitics? so for this I want to have ability
add some additional params for the page from where I made redirect, but when I add
for page1 some params like https://page1?someParam=param or https://page1/param, it updated and show me just https://page1 instead.
I suppose that it's related to way how I created pages. Here is my code:
createPage({
path: `${localePrefix}/${slug}`, // so should I change it here in order to work as needed?
component: PageTemplate,
context: {
...context,
localizedPaths,
},
})
Can it be fixed with?
matchPath: path: ${localePrefix}/${slug}?*,
matchPath: path: ${localePrefix}/${slug}/*,
Recap:
My question is about why gatsby remove query params from pages?
https://some_site/some_page?some_param=323
translates into
https://some_site/some_page
https://page1?someParam=param or https://page1/param are not the same. While a query parameter (first case: ?someParam=param) is an optional value that doesn't change the rendered page (it doesn't point to any specific route hence it's not requesting any file). The second one (https://page1/param) is accessing a /pages/param route.
Since they are URL parameters, you don't need to change anything in your project, you just need to catch them using JavaScript. They are handled in thee:
const urlParams = new URLSearchParams(window?.location?.search);
Note: you can access directly location prop in Gatsby
If your project is replacing https://some_site/some_page?some_param=323 to https://some_site/some_page it's because some server-side configuration or a CDN, not because of Gatsby's behavior, like any other React project.

react-router-dom NavLink doesn't reflect isActive change without refreshing the page

I'm trying to use the NavLink's isActive prop to check whether the link's route is the current route to apply some visual styling.
Whenever I navigate to a page it works correctly as expected. However, if I tap a link while I'm inside a page, the changes aren't reflected to the components. The page and the address (which I presume is using history.pushState, which might be the culprit) updates instantly (without an actual HTTP page reload) but the old page still has the isActive property and the new one doesn't.
If I refresh the page which performs an actual "hard" reload, then the change is reflected.
Here is the relevant parts of the code (with actual paths anonymized) (styles is my imported module CSS with the relevant styles):
function NavigationBar(props:NavigationBarProps){
return <div className={styles['container']}>
<NavLink to={'/first'} className={props => `${styles['link']} ${props.isActive ? styles['selected'] : ''}`}>
first
</NavLink>
<NavLink to={'/second'} className={props => `${styles['link']} ${props.isActive ? styles['selected'] : ''}`}>
second
</NavLink>
<NavLink to={'/third'} className={props => `${styles['link']} ${props.isActive ? styles['selected'] : ''}`}>
third
</NavLink>
</div>
}
What am I doing wrong and how can I get it to work correctly (without implementing path changes manually and without disabling using history API, of course)?
I am on React 18.0.1, React-DOM 18.1.0, React-Router 6.3.0, React-Router-DOM 6.3.0 and connected-react-router 6.9.2.
UPDATE: I've also tried ditching connected-react-router (as it's suggested that it doesn't fully support react-router 6.x and seems like a dead library) and moving completely to https://github.com/salvoravida/redux-first-history yet still have the exact same problem.
UPDATE 2: This problem seems to be happening on Safari. It works correctly on Chrome and Firefox.
Maybe you want something like this example CodeSandbox

is there a way to keep router query on page refresh in nextjs

I have a dynamic page with a dynamic url. everything is clientside rendered.
This is the link that links to the second page
<Link
href= {{ pathname: '/dashboard/[orderdetail]', query: { id: `${orderID}` } }} as={`/dashboard/${orderDetails.orderNo}`}
</Link>
This works well taking every query to the second page. But when I refresh the second page, everything is lost. Every query i had passed is lost
I have tried using with/Router
let orderID=this.props.router.query.orderdetail;
Still on page refresh everything is lost.
I need the query string i am passing to the second page to make a call to a database which works well. But again, when I refresh the page nothing works.
How can I avoid this loss when the page refreshes.
In the end I ended up with this solution, there is no difference here
<Link
href={{
pathname: "/dashboard/" + `${orderDetails.orderNo}`,
query: { id: `${orderID}` },
}} as={`/dashboard/${orderDetails.orderNo}`}
>
</Link>
but adding this in the second page somehow maintains the route query.
export async function getServerSideProps(context) {
return {
props: {}, // will be passed to the page component as props
};
}
How this solves the problem, I don't know, but it does. I do not think there will be that much difference considering I only wanted client-side rendering
Looks like there is some confusion about what query parameters you are working with.
With the href URL object you have in your example the resulting full href URL will be:
/dashboard/[order]?id=nnn
so router.query will contain an order key and an id key, but no orderdetail.
The order key will be set to the content of orderDetails.orderNo with your given as property, but the id will not be set since as has no ?id=xxx part.
Assuming your JS filename is /pages/dashboard/[order].js, your ${orderDetails.orderNo} is accessible as this.props.router.query.order and the id query string is never used.
this.props.router.query.orderdetail as in your code from the question will never be set to anything since the request has no such parameter name.
If instead the filename is /pages/dashboard/[orderdetail].js you need the corresponding
<Link href="/dashboard/[orderdetail]" as={`/dashboard/${orderDetails.orderNo}`}>...</Link>

reactjs routing to a specific section of a different page

from page 1 I am trying to route to a specific section of page 2.
I tried to use the hash value in the Link component but it did not work
<Link to={ {pathname: `/page2`, hash: `#sectionID`}} >
I even used this package react-router-hash-link with no success.
I always end up at the top of page 2.
any help
Check This link for full explanation;
Hash link scroll functionality for React Router, and here is example that will scroll to the component when you open it: baz#section-three, another one baz#section-two

Replace the current url without reloading the page

Using react 16, react-router 4.
My domain is suppose "https://www.xyz.c". I'm having anchor tag which should redirect to "https://www.xyz.c/some-path" without reloading the page.
I can implement it using <NavLink> and <Link> with to="/some-path". However, I need complete url to be shown in DOM (why? Well, on side note, I'm using itemProp for schema for which I want full path in anchor tag)
Implementing it with <a> and props.history tag like following causes to again replace with relative url, i.e. it becomes https://www.xyz.c/https://www.xyz.c/some-path in the url.
<a data-url="https://www.xyz.c/some-path" onClick={this.onClick}>Label</a>
onClick = e => {
e.preventDefault();
this.props.history.push(urlFromDataSet);
}
This seems impossible with <Navlink>, <Link> or <a> + props.history, since the policy is that history.replace, or history.push works on url with same origin. My url is also of same origin, however, I'm giving full path in href.
However, facebook is achieving the same in its header (Check on FB by going to home page, once loaded completely, then Click on your own profile button in header. It doesn't reload the page.)
How can we do that?
You are half there, you can use URL API to get the pathname of your data-url attribute then push it.
const url = new URL(dataUrl)
this.props.history.push(url.pathname)
More information about URL API: https://developer.mozilla.org/en-US/docs/Web/API/URL

Resources