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}`} />
}
Related
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}
);
Hi I am developing an ecommerce site. here I suffer this problem:
Suppose I have an array of product I want to map over the array and hit an post api for all array of items. When all array of items will be post. then I will call another api for getting response.I want to call second api only if the array of elements posted to api.
here is my code :
I am showing all cart items in checkout page. when user want to pay online payment. I place an order and i am getting getway url. I have to clean the cart right? but when my cart cleared the checkout page appearing blank, afer some millisecond page redirect to the gateway URL. I want that after redirect cart will be cleared because if user see blank page it is not good UX.
```await getData(${REST_BASE_API_URL}/mobileapps/orders/${order_id}, {}, userToken())
.then(res => {
let increment_id = res?.increment_id;
if (paymentMethod === 'sslcommerz') {
// navigate('/order-success');
let url = `anything`;
getData(url, {}, userToken())
.then(res => {
window.location.href = res; //redirect to gateway url
dispatch(saveUpdatedCart([])); //cart clear
clearCartAfterOrder(); //set new cart id in redux
console.log('ssl_res', res)
})
.catch(err => {
console.log(err)
})```
I am using navigate to move to another URL. I saw many posts using Link to move to another page with dynamic url. But I want to change url without writing jsx
When I navigate to the following url, I get a 404 error
navigate(`/vidx/${u}`, {
state: { vid: r }
})
I changed gatsby-node.js to following, still getting the same error. I have a file named vidx.js in pages folder
exports.onCreatePage = async ({ page, actions }) => {
const { createPage } = actions
if (page.path.match(/^\/vidx/)) {
page.matchPath = "/vidx/*";
createPage(page);
}
}
My url will look like this - www.xyz.com/vidx/123456789. The number 123456789 will depend upon the user logged in
I want to redirect to vidx.js; but the URL should be /vidx/123456789
That will never work since /vidx/123456789 will always throw a 404 error since it's not generated and doesn't exist, it's a separate new page.
One easy thing you can do use: /vidx?queryParameter=123456789. In that case, your page will remain being /vidx and you can get the queryParameter to make your stuff with your own logic.
I need to fetch the current url in my react application because our front/nginx may respond with a redirect which won't be hit if user has the service-worker active..
therefor I currently have this logic in my 404 component on didMount.
fetch('/test/page/xxxx/', {redirect: 'follow'}).then(res => {
if(res.status === 200 && res.redirected) {
console.log(res)
// this.props.push(res.url)
// window.location.replace(res.url)
// window.location.hash = res.url
console.log('Redirected to ' + res.url)
}
})
the res.url that I get back in the respons is a full url ex: https://example.net/xxx/xxx/xxxx which makes it hard for me to use push from react-router-redux because it expects a relative url. Can anyone help me with a regex that can get the slugs from the res.url or does anyone have any other idea how to solve this problem?
There is the URL interface [1] available in the window that can be used create a URL object.
A URL object has the pathname property that is used to retrieve the path component of the URL.
this.props.push(
new URL(res.url).pathname
)
The easiest way to get the pathname (relative URL) is by parsing it with the URL interface API
const { pathname } = new URL("https://example.net/aaa/bbb/ccc");
console.log(pathname) // "/aaa/bbb/ccc"
In the context of your code
fetch("/test/page/xxxx/", { redirect: "follow" }).then(res => {
if(res.status === 200 && res.redirected) {
const { pathname } = new URL(res.url);
this.props.push(pathname);
}
});
NOTE: Not supported in IE11 and below. If support for that browser is needed, there is a polyfill https://github.com/lifaon74/url-polyfill
There is also a proposal to be added to babel, expected soon to be a stage 0 feature
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.