or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.mdparsers.mdquery-states.mdserialization.mdserver-cache.md

query-states.mddocs/

0

# Query State Management

1

2

Core hooks for managing URL query parameters as React state, providing type-safe synchronization between component state and URL query strings.

3

4

## Capabilities

5

6

### useQueryState

7

8

Manages a single query parameter as React state with type safety and optional default values.

9

10

```typescript { .api }

11

/**

12

* React state hook synchronized with a URL query string in Next.js

13

* @param key - The URL query string key to bind to

14

* @param options - Parser (defines the state data type), default value and optional history mode

15

*/

16

function useQueryState<T>(

17

key: string,

18

options: UseQueryStateOptions<T> & { defaultValue: T }

19

): UseQueryStateReturn<NonNullable<ReturnType<typeof options.parse>>, typeof options.defaultValue>;

20

21

function useQueryState<T>(

22

key: string,

23

options: UseQueryStateOptions<T>

24

): UseQueryStateReturn<NonNullable<ReturnType<typeof options.parse>>, undefined>;

25

26

function useQueryState(

27

key: string,

28

options: Options & { defaultValue: string }

29

): UseQueryStateReturn<string, typeof options.defaultValue>;

30

31

function useQueryState(

32

key: string,

33

options?: Pick<UseQueryStateOptions<string>, keyof Options>

34

): UseQueryStateReturn<string, undefined>;

35

36

function useQueryState(key: string): UseQueryStateReturn<string, undefined>;

37

38

interface UseQueryStateOptions<T> extends Parser<T>, Options {}

39

40

type UseQueryStateReturn<Parsed, Default> = [

41

Default extends undefined ? Parsed | null : Parsed,

42

<Shallow>(

43

value: Parsed | null | ((old: Default extends Parsed ? Parsed : Parsed | null) => Parsed | null),

44

options?: Options<Shallow>

45

) => Promise<URLSearchParams>

46

];

47

```

48

49

**Usage Examples:**

50

51

```typescript

52

import { useQueryState, parseAsInteger, parseAsBoolean } from "nuqs";

53

54

// String query parameter (default type)

55

const [search, setSearch] = useQueryState('q');

56

// search is string | null, setSearch accepts string | null

57

58

// Integer with default value

59

const [page, setPage] = useQueryState('page', parseAsInteger.withDefault(1));

60

// page is number, setPage accepts number | null

61

62

// Boolean with parser options

63

const [active, setActive] = useQueryState('active', {

64

...parseAsBoolean,

65

history: 'push'

66

});

67

68

// Functional updates

69

setPage(oldPage => oldPage + 1);

70

setSearch(null); // Clears the query parameter

71

```

72

73

### useQueryStates

74

75

Manages multiple related query parameters as a single state object with atomic updates.

76

77

```typescript { .api }

78

/**

79

* Synchronise multiple query string arguments to React state in Next.js

80

* @param keyMap - An object describing the keys to synchronise and how to serialise and parse them

81

* @param options - Optional history mode, shallow routing and scroll restoration options

82

*/

83

function useQueryStates<KeyMap extends UseQueryStatesKeysMap>(

84

keyMap: KeyMap,

85

options?: UseQueryStatesOptions & { urlKeys?: Partial<Record<keyof KeyMap, string>> }

86

): UseQueryStatesReturn<KeyMap>;

87

88

type UseQueryStatesKeysMap<Map = any> = {

89

[Key in keyof Map]: KeyMapValue<Map[Key]>;

90

};

91

92

type KeyMapValue<Type> = Parser<Type> & Options & { defaultValue?: Type };

93

94

interface UseQueryStatesOptions extends Options {}

95

96

type Values<T extends UseQueryStatesKeysMap> = {

97

[K in keyof T]: T[K]['defaultValue'] extends NonNullable<ReturnType<T[K]['parse']>>

98

? NonNullable<ReturnType<T[K]['parse']>>

99

: ReturnType<T[K]['parse']> | null;

100

};

101

102

type SetValues<T extends UseQueryStatesKeysMap> = (

103

values: Partial<Nullable<Values<T>>> | UpdaterFn<T> | null,

104

options?: Options

105

) => Promise<URLSearchParams>;

106

107

type UpdaterFn<T extends UseQueryStatesKeysMap> = (old: Values<T>) => Partial<Nullable<Values<T>>>;

108

109

type UseQueryStatesReturn<T extends UseQueryStatesKeysMap> = [Values<T>, SetValues<T>];

110

111

type Nullable<T> = { [K in keyof T]: T[K] | null };

112

```

113

114

**Usage Examples:**

115

116

```typescript

117

import { useQueryStates, parseAsInteger, parseAsBoolean, parseAsString } from "nuqs";

118

119

// Define the query state schema

120

const [filters, setFilters] = useQueryStates({

121

search: parseAsString,

122

page: parseAsInteger.withDefault(1),

123

active: parseAsBoolean.withDefault(true),

124

category: parseAsString

125

});

126

127

// Access individual values

128

console.log(filters.search); // string | null

129

console.log(filters.page); // number (always defined due to default)

130

console.log(filters.active); // boolean (always defined due to default)

131

132

// Update multiple values atomically

133

setFilters({

134

search: 'react',

135

page: 1,

136

category: 'frameworks'

137

});

138

139

// Functional updates with access to current state

140

setFilters(current => ({

141

page: current.page + 1,

142

search: current.search?.toUpperCase()

143

}));

144

145

// Clear all managed query parameters

146

setFilters(null);

147

148

// URL key mapping (use different URL keys than state keys)

149

const [state, setState] = useQueryStates({

150

searchTerm: parseAsString,

151

pageNumber: parseAsInteger.withDefault(1)

152

}, {

153

urlKeys: {

154

searchTerm: 'q',

155

pageNumber: 'p'

156

}

157

});

158

```

159

160

### Options Configuration

161

162

Both hooks support comprehensive configuration options:

163

164

```typescript { .api }

165

interface Options<Shallow = unknown> {

166

/** How the query update affects page history (defaults to 'replace') */

167

history?: HistoryOptions;

168

/** Scroll to top after a query state update (defaults to false) */

169

scroll?: boolean;

170

/** Shallow mode keeps query states update client-side only (defaults to true) */

171

shallow?: Extract<Shallow | boolean, boolean>;

172

/** Maximum time (ms) between URL query string updates (defaults to 50ms) */

173

throttleMs?: number;

174

/** Clear key-value pair from URL when setting state to default value */

175

clearOnDefault?: boolean;

176

/** React transition function for observing Server Component loading states */

177

startTransition?: TransitionStartFunction;

178

}

179

180

type HistoryOptions = 'replace' | 'push';

181

type TransitionStartFunction = (callback: () => void) => void;

182

```

183

184

**Configuration Examples:**

185

186

```typescript

187

// Hook-level options

188

const [search, setSearch] = useQueryState('q', {

189

history: 'push', // Use browser back/forward

190

scroll: false, // Don't scroll on updates

191

throttleMs: 100, // Throttle URL updates

192

clearOnDefault: true // Remove from URL when set to default

193

});

194

195

// Call-level options (override hook options)

196

setSearch('react', {

197

history: 'replace',

198

shallow: false

199

});

200

201

// React 18 transitions for server updates

202

const [isPending, startTransition] = useTransition();

203

const [data, setData] = useQueryState('data', {

204

shallow: false,

205

startTransition

206

});

207

```

208

209

### Error Handling

210

211

The hooks handle various error conditions gracefully:

212

213

- Invalid query string values are parsed as `null`

214

- Parser errors return `null` instead of throwing

215

- URL updates are throttled to prevent browser rate limiting

216

- Multiple hook instances are automatically synchronized