Search code examples
javascriptreactjsrtk-queryhttp-accept-language

Can we override Accept-Language from rtk query endpoints?


This is my baseQuery and I have set the "Accept-Language" header in the prepareHeaders function.

import { fetchBaseQuery, retry } from '@reduxjs/toolkit/dist/query/react'
import i18n from 'i18next';

export const baseQuery = retry(
  fetchBaseQuery({
    timeout: 5000,
    headers: {
      'Content-Type': 'application/json;charset=utf-8',
      'Access-Control-Allow-Origin': '*'
    },
    prepareHeaders: (headers) => {
      if (accessToken) {
        headers.set('Accept-Language', i18n.language);
      }
      return headers;
    },
  }),
  { maxRetries: 3 }
);

What I need is override the "Accept-Language" from the Redux-Toolkit (RTK) Query endpoint.

export const sampleApi = createApi({
  reducerPath: 'sampleApi',
  baseQuery: baseQuery,
  endpoints: (builder) => ({
    getLotteryOdds: builder.query({
      query: () => ({
        url: '/sample',
        method: 'GET',
        headers: {
          'Accept-Language': 'en'
        }
      }),
    }),
  })
})

The way I used above to override is not working. So is there any other way to do that?

I know that if we set "Accept-Language" in baseQuery headers (without using prepareHeaders function), we can override from the RTK endpoint, but my requirement is to set the "Accept-Language" in prepareHeaders and then override it from and endpoint. How can I do that?


Solution

  • prepareHeaders is the "last stop", overwriting anything previously setting headers. You could check that the "Accept-Language" header already has a value and only set it to a default if it isn't.

    Example:

    import { fetchBaseQuery, retry } from '@reduxjs/toolkit/dist/query/react';
    import i18n from 'i18next';
    
    export const baseQuery = retry(
      fetchBaseQuery({
        timeout: 5000,
        headers: {
          'Content-Type': 'application/json;charset=utf-8',
          'Access-Control-Allow-Origin': '*',
        },
        prepareHeaders: (headers) => {
          if (!headers.has('Accept-Language') && accessToken) {
            headers.set('Accept-Language', i18n.language);
          }
          return headers;
        },
      }),
      { maxRetries: 3 },
    );
    
    export const sampleApi = createApi({
      reducerPath: 'sampleApi',
      baseQuery,
      endpoints: (builder) => ({
        getLotteryOdds: builder.query({
          query: () => ({
            url: '/sample',
            method: 'GET',
            headers: {
              'Accept-Language': 'en'
            }
          }),
        }),
      }),
    });
    

    You could pass data from the endpoint to the base query function via the extra options argument and perform a similar check.

    Example:

    import { fetchBaseQuery, retry } from '@reduxjs/toolkit/dist/query/react';
    import i18n from 'i18next';
    
    export const baseQuery = retry(
      fetchBaseQuery({
        timeout: 5000,
        headers: {
          'Content-Type': 'application/json;charset=utf-8',
          'Access-Control-Allow-Origin': '*',
        },
        prepareHeaders: (headers, { extra }) => {
          if (extra.headers.acceptLanguage) {
            headers.set('Accept-Language', extra.headers.acceptLanguage);
          } else if (accessToken) {
            headers.set('Accept-Language', i18n.language);
          }
          return headers;
        },
      }),
      { maxRetries: 3 },
    );
    
    export const sampleApi = createApi({
      reducerPath: 'sampleApi',
      baseQuery,
      endpoints: (builder) => ({
        getLotteryOdds: builder.query({
          query: () => ({
            url: '/sample',
            method: 'GET',
          }),
          extraOptions: {
            headers: {
              acceptLanguage': 'en',
            },
          },
        }),
      }),
    });