How to construct a query based URL in react - reactjs

I have an app that takes a search string and returns results in one route : hosts.abc.com:3000. The url doesn't change.
I want the search to be reflected in the url so I can share the link and users don't have to make all selection in the form fields.
eg: hosts.abc.com:3000/?type=all&query=coins
Is it possible to do this using react-router ?

To construct such query you could use native browser URLSearchParams:
const searchParams = new URLSearchParams();
searchParams.append("type", "all");
searchParams.append("query", "coins");
searchParams.toString(); // "type=all&query=coins"
// update browser url
this.props.history.push('/current/route/?' + searchParams.toString());
// or
this.props.history.push({
pathname: '/current/route/',
search: searchParams.toString()
})
But if you want better support query-string is a similar option.

Related

How to add URL args depending on content in NextJS React web app? [duplicate]

I am developing a ecommerce store using NEXT.JS and Redux. So in product listing page, I have sorting select dropdown with Price Low to High, Price High to Low and New Arrivals. Upon selecting this option, I want to change the URL without page refresh and API call should occure. I have tried using below code, but it is not working and page is reloading.
function sortBy(value) {
router.replace({
pathname: '/products/'+slug,
query: { sort: value }
})
dispatch(fetchproducts(slug, sort));
}
The above code just refresh the current page and appending sort param to URL.
So is it possible to do it without page refresh like in Flipkart.
With the help of shallow-routing change of URL without doing a page reload is possible. It can be enabled by passing explicit option object as third argument to Router.push, i.e { shallow: true }
From the docs
Shallow routing allows you to change the URL without running data fetching methods again, that includes getServerSideProps, getStaticProps, and getInitialProps.
You'll receive the updated pathname and the query via the router object (added by useRouter or withRouter), without losing state.
For example, this how you would update the query param sortBy for pathname /products with the help of shallow-routing.
Router.push({
pathname: '/products',
query: { sortBy: 'price' }
},
undefined, { shallow: true }
)
But there are a few caveats It is not possible to do shallow-routing between different pages, it works only for same page URL changes. See the caveat section for more details.
For example, you can update a query param for page /product page, but it won't be possible if you try to do shallow-routing from /product to /product/[slug] because they are two distinct pages.
// page will reload because shallow-routing not possible between the pages
Router.push('/product', '/product/some-product?sortBy=price', { shallow: true })
Example:
you have a folder like: posts/[id].js and your url is like http://something.com/posts/123
You want to add a query param that will not refresh the page and your url will be like: http://something.com/posts/123?param=ok
all you need to do is:
const postId = 123;
const param = 'ok';
router.push(
{
pathname: `/posts/[id]`,
query: {
postId,
param
}
},
`/posts/${postId}?param=${param}`,
{shallow: true}
);

How to pass multiple queries in next router

I am working in next.js and next-router
I have 2 data parameters that I want to pass
One is entity_id and the other is url_key.
data={
entity_id: 5,
url_key: 'canada/ontario/store_five'
}
Currently I am able to pass one url_key:
Router.push('/store?url_key=' + marker.url_key, `/store/${marker.url_key}`)
The URL is appearing just as I wanted like
http://BaseUrl/store/canada/ontario/store_five
Now I want to also send entity_id along with above url_key but that should not display in URl
You can pass as many query params as you want, it just using query-string.
// using urls
Router.push(
`/store?url_key=${marker.url_key}&entity_id=${marker.entity_id}`,
`/store/${marker.url_key}`
);
// using object
Router.push({
pathname: '/store',
query: { url_key: marker.url_key, entity_id: marker.entity_id },
asPath: `/store/${marker.url_key}`,
});
For more info, read router docs
I would suggest you use a query object to pass multiple queries in next router. Using package
import {useRouter} from "next/router";
const router=useRouter();
router.push({
pathname:'/store',
query:{entity_id :"2221ACBD",url_key:"URL KEY"},
})
To fetch the data from the query you can use array destructuring of query like this :
const { query } = useRouter();
console.log("query::",query);
console.log("entity key:-",query.entity_id);
console.log("url_key:-",query.url_key);
Example : Example1

React URL param redirect

I am currently working with react and react-router and I'm building a page that shows details of a certain item that gets its data from an API when the page mounts. The fetch method requires the item's id so I'm using match.params.id to get the value for the fetch method. I also am using the slug package in the backend to show the title for that item in URL format alongside the id. I want users to be able to type in the URL with the slug title and not have to worry about typing the id in order to be directed to the page with the correct data.
For example, clicking on the item on the UI will make the URL look like this: localhost:3000/the-title-slug/123456.
You have to actually click on the item on the UI to get the URL to have the id but I want to make things simpler for the user and make it so that if they only type the slug title: localhost:3000/the-slug-title, it will redirect to the correct URL with that slug and id.
Any ideas on how this could be done? Kind of like if you type googel.com it corrects the typo and directs you to google.com. Any help figuring this out would be very appreciated, thank you.
Your backend must to have the API method to get correct item by misspelled slug.
like:
requestData: the-slug-title
responseData: the-title-slug, 123456
and then your component have to handle wrong url
componentDidMount() {
const { params } = this.props.match;
const respose = await fetch({ ... })
this.setState({ id: response.id, slug: response.slug });
}
render() {
const { params } = this.props.match;
return this.state.id && this.state.slug && (this.state.id !== params.id || this.state.slug !== params.slug) && <Redirect to={`/${this.state.slug}/${this.state.id}`} />
}

How do I pass a custom parameter to nextjs dynamic route so I can access it inside getInitialProps

I want to pass an ID as a custom parameter to next/link <Link /> and be able to access it inside getInitialProps. I want to use clean URL's but the API i'm using only allows you to query it via the post ID. So while I can access the post slug inside getInitialProps I cant use it to query the post.
I currently have it set up to use the post slug in the URL
<Link href="/article" as={`/article/${urlPattern}`}>
<a>{title}</a>
</Link>
and in getInitialProps I can access the slug via the context parameter
Article.getInitialProps = async context => {
const slug = context.query;
// need query ID
// do api call
};
Is there a way I can pass the ID to so I can access it inside getInitialProps via the context to do my API call?
** EDIT **
I've updated the by adding a query property which allows me to access the id via context.query.id but doing so also updates the page URL to /article/the-article-title?id=234234324324 I dont want the URL to include the article id just the article name but I still need a way to access the article ID inside getInItialProps so I do the api call.
<Link
href="/article/[article]"
as={{
pathname: `/article/${urlPattern}`,
query: { id: system.id }
}}
>
You could pass an URL object to the as prop:
<Link
href={"/article"}
as={{
pathname: "/article",
query: { id: "query id" }
}}
>
<a>title</a>
</Link>
There is an example: https://github.com/zeit/next.js/tree/master/examples/with-url-object-routing

Persist url query data in reactjs

I am using react and in some pages i am transferring data from url but the problem is when I want that data to persist if url changes until there is any other query or parameter in url.
How can i achieve that?
This is my url snapshot
I want the query data i.e idx=1 to persist if there is any change in url like this
Currently when I link to salesfunnel page I am doing this
`
componentDidMount() {
var url = this.props.location.query;
this.setState({
selid : parseInt(url.idx, 10)
})
}
`
and in that case i lost query.I want that the query should remain somewhere with me if i get it once and the data should only change when there is certain change in query of url for eg: if idx=2 from idx=1.
How can i achieve that in react?
Any help much appreciated!
Thanks :)
Can you not conditionally set the selid e.g.:
componentDidMount() {
var url = this.props.location.query;
if (url.idx) {
// Only update `selid` when `idx` is a query param
this.setState({
selid : parseInt(url.idx, 10)
});
}
}
This way you'll persist the value across page changes until the user lands on a new page that sets a new idx.

Resources