stormy-gold
stormy-gold4w ago

Leverage Querystring parameters

In a page, I want to be able to set querystring parameters in order to restore the view when a user directly access the page containing these querystring parameters the way pageSize and current works for table views. How can I achieve that in refine ?
5 Replies
kapa.ai
kapa.ai4w ago
Hi @quick691. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- You can leverage query string parameters in refine to restore the view state when a user directly accesses a page, similar to how pageSize and current work for table views. This is achieved using the syncWithLocation feature. Using syncWithLocation The syncWithLocation feature allows you to encode state in URL query parameters and automatically restore that state when the URL is accessed directly. By default, this feature is disabled, but you can enable it in two ways: 1. Globally in the <Refine /> component:
<Refine
// other props
options={{ syncWithLocation: true }}
>
{/* ... */}
</Refine>
<Refine
// other props
options={{ syncWithLocation: true }}
>
{/* ... */}
</Refine>
2. Per hook in components like useTable:
const { tableProps } = useTable({
syncWithLocation: true,
});
const { tableProps } = useTable({
syncWithLocation: true,
});
When enabled, parameters like filters, pagination, and sorting will be automatically encoded in the URL, making it easy to share or bookmark specific views Blog > Building a CRUD app with Material UI and Strapi in React. Accessing and Manipulating URL Parameters To access the current URL parameters, you can use the useParsed hook:
import { useParsed } from "@refinedev/core";

const MyComponent = () => {
const {
params: {
filters,
sorters,
current,
pageSize,
...restParams // Any other custom parameters
},
} = useParsed();

// Use the parameters to restore your view state
};
import { useParsed } from "@refinedev/core";

const MyComponent = () => {
const {
params: {
filters,
sorters,
current,
pageSize,
...restParams // Any other custom parameters
},
} = useParsed();

// Use the parameters to restore your view state
};
To navigate with specific query parameters, you can use the useGo hook:
import { useGo } from "@refinedev/core";

const MyComponent = () => {
const go = useGo();
const handleClick = () => {
go({
to: "/my-resource",
query: {
filters: [
{
field: "title",
operator: "contains",
value: "Refine",
},
],
myCustomParam: "value",
},
type: "push",
});
};

return <button onClick={handleClick}>Go to filtered view</button>;
};
import { useGo } from "@refinedev/core";

const MyComponent = () => {
const go = useGo();
const handleClick = () => {
go({
to: "/my-resource",
query: {
filters: [
{
field: "title",
operator: "contains",
value: "Refine",
},
],
myCustomParam: "value",
},
type: "push",
});
};

return <button onClick={handleClick}>Go to filtered view</button>;
};
Server-Side Rendering Support If you're using Next.js with SSR, you'll need to handle the query parameters during server-side rendering. You can use the parseTableParams utility:
// For App Router
import { parseTableParams } from "@refinedev/nextjs-router";

// For Pages Router
import { parseTableParams } from "@refinedev/nextjs-router/pages";

// Then in your SSR function
const tableParams = parseTableParams(searchParams);

// Use tableParams with your data provider
const data = await dataProvider.getList({
resource: "posts",
...tableParams, // includes filters, sorters and pagination
});
// For App Router
import { parseTableParams } from "@refinedev/nextjs-router";

// For Pages Router
import { parseTableParams } from "@refinedev/nextjs-router/pages";

// Then in your SSR function
const tableParams = parseTableParams(searchParams);

// Use tableParams with your data provider
const data = await dataProvider.getList({
resource: "posts",
...tableParams, // includes filters, sorters and pagination
});
This approach ensures that your view state is properly restored when users access your page directly with query parameters Documentation > Docs > Routing > Integrations > Next.js > FAQ. By using these features, you can create shareable and bookmarkable views in your refine application, just like the built-in table views do with pagination and filtering. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai4w ago
<@347285614531444756> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
stormy-gold
stormy-goldOP4w ago
@kapa.ai I have a problem, it seems useTable is overriding query string parameters after my call to go() method and the pageSize and current is added to querystring to manage table but my additionnal parameters set with go are not changed.
kapa.ai
kapa.ai4w ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- I understand your issue with useTable overriding query string parameters after using the go() method. This is a known behavior in refine where syncWithLocation works in one direction only. The Issue The problem you're experiencing is that useTable with syncWithLocation enabled: 1. Initially infers parameters from query params when mounted 2. Stores these values in its internal state 3. Updates the query params when its internal state changes 4. Does not sync back from URL to internal state if the URL changes from outside the hook As explained in a GitHub issue:
syncWithLocation works in one direction and only infers the parameters at initial render to avoid syncing issues with the state and the query params... If there are any changes in the query params that is not caused by useTable and if those changes don't re-mount the hook, those changes are not synced with the internal states.
Github Issue: not clear filters and sorters when clicking menu item Workaround Solution You can implement a workaround by adding an effect that monitors URL changes and updates the table state accordingly:
import { useParsed } from "@refinedev/core";
import { useTable } from "@refinedev/core"; // or your UI library's useTable
import React from "react";

const MyComponent = () => {
const { params } = useParsed();
const { setFilters, setSorters } = useTable();

React.useEffect(() => {
// Check if URL parameters exist and update table state accordingly
if (params.filters) setFilters(params.filters, "replace");
if (params.sorters) setSorters(params.sorters);
// Add handling for your custom parameters here if needed
}, [params]);

// Rest of your component
};
import { useParsed } from "@refinedev/core";
import { useTable } from "@refinedev/core"; // or your UI library's useTable
import React from "react";

const MyComponent = () => {
const { params } = useParsed();
const { setFilters, setSorters } = useTable();

React.useEffect(() => {
// Check if URL parameters exist and update table state accordingly
if (params.filters) setFilters(params.filters, "replace");
if (params.sorters) setSorters(params.sorters);
// Add handling for your custom parameters here if needed
}, [params]);

// Rest of your component
};
This effect will monitor changes in the URL parameters and update the table's internal state when they change, creating a two-way binding between the URL and the table state. The refine team has acknowledged this limitation and mentioned they've discussed potential improvements to implement proper two-way binding, but it hasn't been prioritized yet. If you need more specific help with your implementation, please share more details about your code and what additional parameters you're trying to preserve. Would you like me to provide a more detailed example based on your specific use case? ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai4w ago
<@347285614531444756> Kapa.ai is still learning and improving, please let me know how I did by reacting below.

Did you find this page helpful?