Get the latest insights, best practices, and tips from power users

Hygraph
Docs

Exchanging and using app tokens

#Overview

This document shows how to generate an app token for your app, while your app is installing. Make sure you have the ClientID and the Client Secret of your app before you start.

#Step by step

Assuming you created your app using create-next-app, your app's setup page should look similar to the example below if you're working with app tokens. Notice the section under the comment, which you need to modify as in the example:

import { useApp, Wrapper } from '@hygraph/app-sdk-react';
function Setup({ code }: { code: string }) {
const { context } = useApp();
const managementApiBaseUrl = context.project.mgmtApi.split("/")
.slice(0, -1)
.join("/");
return (
<Button
onClick={() =>
fetch(`/api/saveAppToken`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
code,
environmentId: context.environment.id,
managementApiBaseUrl,
}),
})
.then((res) => res.json())
.then((data) => {
// Save token to localstorage
localStorage.setItem('app-token', data.appToken);
})
}
>
Get App Token
</Button>
);
}
// You'll get the exchange code in your setup page as query param only while
// your App Installation is not completed
export default function SetupPage() {
const { query } = useRouter();
return (
<Wrapper>
<Setup code={query.code as string} />
</Wrapper>
);
}

In the above example const { query } = useRouter() was added to get the code from the query, and Setup code={query.code as string} was added to pass the code in the setup component.

The next step is to create a new API route /api/saveAppToken.ts. This is the file where your app token will be generated:

export default async function handler(
req: NextApiRequest,
res: NextApiResponse<Data>
) {
const body = req.body as { code: string; environmentId: string; managementApiBaseUrl: string; };
const response = await fetch(`${managementApiBaseUrl}/app-exchange-token`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
clientId: process.env.CLIENT_ID,
clientSecret: process.env.CLIENT_SECRET,
exchangeCode: req.body.code,
}),
});
const { appToken } = (await response.json()) as { appToken: string };
// Return App token to the browser so it can save it in localstorage
res.status(200).json({ appToken });
}

Now you can pass the saved app token in your header for authorization. For example, to create a new model using the saved app token, you can create another API route /api/createHygraphModel.ts:

const createModelMutation = `
mutation CreateModelMutation($input: CreateModelInput!) {
createModel(data: $input) {
migration {
id
}
}
}
`;
export default async function handler(
req: NextApiRequest,
res: NextApiResponse<Data>
) {
// Get App token from the client, saved in localstorage, in the request body
const body = req.body as { appToken: string; environmentId: string; managementApiUrl: string; };
const response = await fetch(managementApiUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${body.appToken}`,
},
body: JSON.stringify({
query: createModelMutation,
variables: {
input: {
environmentId: body.environmentId,
apiId: '<your_model_api_id>',
apiIdPlural: '<your_model_api_id_plural>',
displayName: '<Your model display name>',
description: '<Your model description>',
},
},
}),
});
res.status(200).json(response);
}

And here is the frontend code for invoking this API route:

import { useApp, Wrapper } from '@hygraph/app-sdk-react';
function CreateHygraphModel({ code }: { code: string }) {
const { context } = useApp();
const managementApiUrl = context.project.mgmtApi;
return (
<Button
onClick={() =>
fetch(`/api/createHygraphModel`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
appToken: /* Get Saved App Token */,
environmentId: context.environment.id,
managementApiUrl,
}),
})
.then((res) => res.json())
.then((data) => {
console.log('🎉 Created Hygraph Model');
})
}
>
Create Hygraph Model
</Button>
);
}
// Remember to wrap the component in Hygraph App Wrapper
export default function SetupPage() {
const { query } = useRouter();
return (
<Wrapper>
<CreateHygraphModel />
</Wrapper>
);
}

#Resources

  • App Framework: Overview to our App Framework, which extends Hygraph capabilities, offering the possibility of creating your own custom apps and sharing them with other users.
  • Migrate to apps: A guide on migrating from UIX to app.
  • Register an app: Documentation for developers on how to register an app on the Hygraph platform.
  • Install an app: Step by step guide on how to install an app in your Hygraph project.
  • Delete an app: Documentation for developers on how to delete an app you have created.
  • First steps: Comprehensive step-by-step guide on how to develop an app with custom field and sidebar elements.
  • Next.js starter: Document that guides you through the process of developing an app with a custom field using our Next.js starter.
  • API Reference: Our App Framework API Reference.