Overview
A centralized module of React hooks and utilities for type-safe URL query parameter management using the nuqs library, providing shallow routing without full page refreshes.
Description
The use-query-params module provides three specialized hooks and one utility function built on top of the nuqs library for managing application state through URL query parameters:
- usePricingModal manages a boolean modal state via the ?pricing=open query parameter. It uses a custom createParser that maps the string value open to true and serializes true back to open. History mode is set to push so the modal open state creates a new browser history entry.
- useAccountSettingModal manages the account settings modal state via ?action=showSettings&tab={tab} query parameters using useQueryStates for atomic multi-parameter updates. The setter intelligently chooses between push and replace history modes: it pushes a new entry when first opening the modal and replaces when switching tabs within an already-open modal. The hook returns a tuple of { isOpen, payload } state and a setter that accepts { payload: T } or null.
- usePluginInstallation manages plugin installation state via ?package-ids and ?bundle-info query parameters. The parseAsPackageId parser handles JSON-encoded arrays (extracting the first element) and plain strings. The parseAsBundleInfo parser validates and extracts org, name, and version fields from a JSON string.
- clearQueryParams is a non-hook utility function that imperatively removes one or more query parameters from the current URL using window.history.replaceState, with a server-side guard to prevent execution during SSR.
Usage
Use these hooks in any client component that needs to synchronize UI state with URL query parameters. They are the standard mechanism in Dify for controlling modal visibility, plugin installation flows, and other URL-driven state through type-safe, shallow-routing-aware abstractions.
Code Reference
Source Location
Signature
export function usePricingModal(): [boolean, (value: boolean) => void]
export function useAccountSettingModal<T extends string = string>():
readonly [{ isOpen: boolean; payload: T | null }, (state: { payload: T } | null) => void]
export function usePluginInstallation(): [
{ packageId: string | null; bundleInfo: BundleInfoQuery | null },
(state: { packageId?: string | null; bundleInfo?: BundleInfoQuery | null } | null) => void,
]
export function clearQueryParams(keys: string | string[]): void
Import
import {
usePricingModal,
useAccountSettingModal,
usePluginInstallation,
clearQueryParams,
} from '@/hooks/use-query-params'
I/O Contract
Inputs (usePricingModal)
| Name |
Type |
Required |
Description
|
| (none) |
- |
- |
No arguments; reads and writes the ?pricing query parameter
|
Outputs (usePricingModal)
| Name |
Type |
Description
|
| isOpen |
boolean |
Whether the pricing modal is currently open (?pricing=open is present)
|
| setIsOpen |
(value: boolean) => void |
Setter to open or close the pricing modal by updating the URL
|
Inputs (useAccountSettingModal)
| Name |
Type |
Required |
Description
|
| (none) |
- |
- |
No arguments; reads and writes ?action and ?tab query parameters
|
Outputs (useAccountSettingModal)
| Name |
Type |
Description
|
| state.isOpen |
boolean |
Whether the account setting modal is open
|
| state.payload |
null |
The currently selected tab within the modal, or null if closed
|
| setState |
null) => void |
Setter to open the modal to a specific tab or close it by passing null
|
Inputs (usePluginInstallation)
| Name |
Type |
Required |
Description
|
| (none) |
- |
- |
No arguments; reads and writes ?package-ids and ?bundle-info query parameters
|
Outputs (usePluginInstallation)
| Name |
Type |
Description
|
| state.packageId |
null |
The parsed package ID from the URL
|
| state.bundleInfo |
null |
The parsed bundle info object (org, name, version) from the URL
|
| setState |
setter function |
Setter to update or clear the plugin installation query parameters
|
Inputs (clearQueryParams)
| Name |
Type |
Required |
Description
|
| keys |
string[] |
Yes |
One or more query parameter keys to remove from the current URL
|
Outputs (clearQueryParams)
| Name |
Type |
Description
|
| (none) |
void |
Imperatively updates the URL; no return value
|
Usage Examples
Controlling the Pricing Modal
import { usePricingModal } from '@/hooks/use-query-params'
function UpgradeButton() {
const [isOpen, setIsOpen] = usePricingModal()
return (
<>
<button onClick={() => setIsOpen(true)}>View Pricing</button>
{isOpen && <PricingModal onClose={() => setIsOpen(false)} />}
</>
)
}
Opening Account Settings to a Specific Tab
import { useAccountSettingModal } from '@/hooks/use-query-params'
function BillingLink() {
const [accountModal, setAccountModal] = useAccountSettingModal()
return (
<>
<button onClick={() => setAccountModal({ payload: 'billing' })}>
Manage Billing
</button>
{accountModal.isOpen && (
<AccountSettingModal
activeTab={accountModal.payload}
onClose={() => setAccountModal(null)}
/>
)}
</>
)
}
Clearing Query Parameters After Processing
import { clearQueryParams } from '@/hooks/use-query-params'
function CallbackHandler() {
useEffect(() => {
// Process the callback parameters, then clean up the URL
handleCallback()
clearQueryParams(['code', 'state', 'error'])
}, [])
return <div>Processing...</div>
}
Related Pages
Page Connections
Double-click a node to navigate. Hold to expand connections.