Skip to content

Custom queryKey generation for @tanstack/react-query pluginΒ #2040

@SergGrey1992

Description

@SergGrey1992

The current implementation of queryKey generation in the @tanstack/react-query plugin includes the baseUrl in the queryKey:

[ { "_id": "getAllCountry", "baseUrl": "https://api.test.local/nsi" }]
This creates significant issues when working with multiple environments. For example:

server: http://localhost:8000/nsi/v1/countries
client (brouser): https://api.test.local/nsi/v1/countries

Including the baseUrl in the queryKey means that:

Switching environments creates new cache entries instead of reusing existing ones
Testing becomes more difficult since queryKeys differ between environments
Manual cache manipulation requires knowing the exact baseUrl for each environment

Current Implementation
The current implementation looks like this:

const createQueryKey = <TOptions extends Options>(
  id: string,
  options?: TOptions,
  infinite?: boolean
): [QueryKey<TOptions>[0]] => {
  const params: QueryKey<TOptions>[0] = {
    _id: id,
    baseUrl: (options?.client ?? _heyApiClient).getConfig().baseUrl,
  } as QueryKey<TOptions>[0];
  if (infinite) {
    params._infinite = infinite;
  }
  if (options?.body) {
    params.body = options.body;
  }
  if (options?.headers) {
    params.headers = options.headers;
  }
  if (options?.path) {
    params.path = options.path;
  }
  if (options?.query) {
    params.query = options.query;
  }
  return [params];
};

Feature Request
I'd like the ability to customize the queryKey generation, particularly to exclude the baseUrl or modify how it's structured.
Proposed Solution
Add a queryKeyBuilder option to the @tanstack/react-query plugin config:

export default {
  plugins: [
    {
      name: '@tanstack/react-query',
      queryKeyBuilder: (id, options, infinite) => {
        // Custom implementation to build queryKey that omits baseUrl
        const params = { _id: id };
        
        if (infinite) params._infinite = infinite;
        if (options?.body) params.body = options.body;
        if (options?.path) params.path = options.path;
        if (options?.query) params.query = options.query;
        
        return [params]; // Return without baseUrl
      }
    }
  ]
}

Or a simpler option to just disable baseUrl inclusion:

export default {
  plugins: [
    {
      name: '@tanstack/react-query',
      includeBaseUrlInQueryKey: false // Simple flag to exclude baseUrl
    }
  ]
}

Impact

This enhancement would:

Improve cache consistency across environments

Reduce the size of queryKeys
Make manual cache operations more predictable
Support more complex caching strategies

Technical Details

The implementation would need to modify the queryKey generation to either:

Use a user-provided function for queryKey generation

Apply a set of configuration options to control what gets included

Workarounds

Until this feature is implemented, users need to either:

Override queryKey for each hook call

Use a global QueryClient with a custom queryKeyFactory
Create wrapper hooks to transform the queryKeys

These solutions add extra code and complexity that could be avoided with a proper configuration option.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions