Postgrest has a really snazzy feature where you can set the 'Accept: application/geo+json' header to get your results as geojson instead of simple rows.

And Maplibre has a handy function where you can pass in a request transformer to alter all your requests to a source, like this:

function customRequestTransformer(url: string): RequestParameters {     
    const params = {
      url: url,
      headers: {
        Authorization: `Bearer ${user.access_token}`,
        Accept: 'application/geo+json',
    return params;


But if you do that, you'll see that your Authorization header is added, BUT your Accept one is not. Arrgg!

Annnnd I wrote the below while I was trying to find a fix, but instead I just wrote the fix and pushed it upstream at . Enjoy! The next release of Maplibre-gl-js will work properly with Postgrest now.

Open source is great.

(Below, if anyone is curious)

The culprit is here:

    if (requestParameters.type === 'json') {
        request.headers.set('Accept', 'application/json');

and then, here

export const getJSON = <T>(requestParameters: RequestParameters, abortController: AbortController): Promise<{data: T} & ExpiryData> => {
    return makeRequest(extend(requestParameters, {type: 'json'}), abortController);

and finally, here:

async loadGeoJSON(params: LoadGeoJSONParameters, abortController: AbortController): Promise<GeoJSON.GeoJSON> {
        const {promoteId} = params;
        if (params.request) {
            const response = await getJSON<GeoJSON.GeoJSON>(params.request, abortController);

So loadGeoJSON calls getJSON, which always sets type: 'json', which means our final request nukes whatever request headers we had set.