GraphQL Error (Code: 401): {"response":{"data":[{"id":"5413bc","type":"api_error","attributes":{"code":"INVALID_AUTHORIZATION_HEADER"

datocms_env_api_token_error

I am using the code from ./lib/datocms.js
I get this error if I pull the API token from .env.local like so:
authorization: Bearer ${process.env.NEXT_ENV_DATOCMS_API_TOKEN}

However, if I use the API token literally everything works:
authorization: ‘Bearer ed49a2531885ebb…’ (of course I use the correct token without the …)

What am I missing?

import { GraphQLClient } from "graphql-request";

export async function request(query, {variables, preview} = {} ) {

  // console.log('request', { query, variables, preview });

  if (!preview || !variables) {
    return
  }

  const endpoint = preview
    ? `https://graphql.datocms.com/preview`
    : `https://graphql.datocms.com/`;
    
  const client = new GraphQLClient(endpoint, {
    headers: {
      // authorization: 'Bearer ed49a2531885ebb....',
      authorization: `Bearer ${process.env.NEXT_ENV_DATOCMS_API_TOKEN}`,
    }
  });
  return client.request(query, variables);
}

So could anyone point me to the right direction? Thanks

Hello @khoophdev, and welcome to the community!

Could you try and create a .env file in the folder of your project with the content being something like:

NEXT_ENV_DATOCMS_API_TOKEN=your_api_token_here

And seeing if the error persists?

Thank you

Hi,
Thanks for replying to my question.
This is exactly what I have. I am the NextJs DatoCMS blog project template.

What I noticed is that the issue the error does not happen on requests made server-side (getStaticProps() and getStaticPaths()) when using authorization: Bearer ${process.env.NEXT_ENV_DATOCMS_API_TOKEN}

The error happens client-side where it seems that the client does not have access to NEXT_ENV_DATOCMS_API_TOKEN. That’s why it only works when the token is hard-coded in the api call header., which is not the way to go.

I hope it is an accurate assessment of the issue

I missed your reply @khoophdev, sorry for the delay

Are you executing that function exclusively on the server-side? If you try to run it from the client side at some point, the client won’t have access to the process global object, as it is exclusive to the node server, and it would generate an authentication error.

You can’t really do a graphQL request directly from the client side, as that would require you to provide the API key to the user (you can think of it as trying to do a database request from the user, you can’t really do it without providing your database key, so it must always be done on the server-side)

Since you are using Next, an easy way to solve this is to do the queries exclusively on the server-side rendering functions ( getStaticProps or getServerSideProps), this way the queries are made on the server side and are then pre-rendered when you pass them to the react component, keeping your token safe.

Sweet! Thanks for the explanation.
Indeed, I was making the requests client-side and I could not access server-side env configs.
However, I got not luck getting it to work with getServerSideProps/getStaticProps, but with useEffect hooks!!!

I will revisit to investigate further.

Now I have to resolve CORS issues accessing “https//…bahobab.vercel.app/api/datocmsquery” after deployment to vercel.

I think this article will help: How can I enable CORS on Vercel? – Vercel Docs
Will see…

Again, thanks for the lead :+1: :+1:

1 Like

Hi, I’m also having this problem, did you get it? How?

I’m using getStaticProps

export const getStaticProps = async (context: any) => {
  const myQuery = `
    query MyQuery {
      banner {
        title
        content
        image {
          url
        }
    }
    `;

  const graphqlRequest = {
    query: myQuery,
    preview: context.preview,
  };

  return {
    props: {
      subscription: context.preview
        ? {
            ...graphqlRequest,
            initialData: await request(graphqlRequest),
            token: process.env.NEXT_DATOCMS_API_TOKEN,
          }
        : {
            enabled: false,
            initialData: await request(graphqlRequest),
          },
    },
    revalidate: 1000 * 60 * 1, 
  };
};

lib/datocms.ts

import { GraphQLClient } from "graphql-request";

export function request({ query, variables, preview }: any) {
  const endpoint = preview
    ? `https://graphql.datocms.com/preview`
    : `https://graphql.datocms.com/`;
  const client = new GraphQLClient(endpoint, {
    headers: {
      "Content-Type": "application/json",
      authorization: `Bearer ${process.env.NEXT_DATOCMS_API_TOKEN}`,
    },
  });
  return client.request(query, variables);
}

Hello @paulorobyson and welcome to the community!

Can you console.log(process.env.NEXT_DATOCMS_API_TOKEN) so we can see if you are getting access to that environment variable from inside your project?

Hello @m.finamor , thank you very much!

Of course, follow…

@paulorobyson taking a look at your project, that seems to be the Read Only API token, could you try and substitute it by the Full access API token and see if the problem persists?

I’ve already tried with the Full access API token and also even created a new key to test.

In development it works, the problem is only at the time of deploy in Vercel.

Oh, in that case, are you setting this key at vercels dashboard: https://vercel.com/docs/concepts/projects/environment-variables
as NEXT_DATOCMS_API_TOKEN: YOUR_KEY

Hello @m.finamor

All right!!! :grinning:

Thank you revy much for your help!

1 Like

Just in case this helps anyone else, because this thread was my first hit when troubleshooting: I had a similar problem that turned out to be a specific string of $% within my NEXT_DATOCMS_PREVIEW_SECRET variable (because I just mashed the keyboard to generate it). Removing that suddenly made the starter template start working.

1 Like