App reviews, troubleshooting, and recommendations
I am developing a shopify app with the Remix template. My app provides a theme app extension for shopify stores.
The logic is following: the theme app extension adds a submit form on the shop frontend; a user submit some details on this form. Then the backend of the app gets the POST request, then create a GraphQL client that makes a query to DB based on submitted details.
My question is following: how should I create a GraphQL client getting the POST request from a store frontend?
I found shopify.authenticate and shopify.unauthenticated
If I understand it correctly, I should use shopify.authenticate getting the POST request from a store frontend (because it's said that I cannot use shopify.unauthenticated if the request coming from Shopify).
So, I am using shopify.authenticate.public to get the session token to use it after for the GraphQL client.
But I am getting an error trying to get the session token. What I am doing wrong?
Here is the code:
-------
// Here I am handling the POST request from a shop frontend
I think you're probably facing this issue outlined here. I've just lost many hours to it. I hate to come across negative but it's hard to stay cool when we are dealing with issues like this 🙂
edit: Having thought about this more - surely it is not actually a problem and we're doing something wrong. The app would not work if the token wasn't working. I just can't work out what is wrong.
I have managed to work around the issue. I'm sure it's not really best practice but it works.
I found the accessToken being stored in the shopify_sessions table of the database. I'm using postgres, but you'd be able to find it in whatever storage you're using.
So I'm making a request to the database to fetch the access token, I'm extracting the shop by accessing sessionToken.input_data.shop.domain, and then making the graphql request.
Here's how I've implemented it with some helper functions..
Remix action
export const action = async ({ request }) => {
const { cors, sessionToken } = await authenticate.public.checkout(request);
const shop = sessionToken.input_data.shop.domain;
// call to storage for access token
const accessToken = await fetchAccessToken(shop)
const productId = '123456789';
const product = await getProduct({ shop, accessToken, productId });
console.log(product)
// rest of code...
};
getProduct()
export default async function getProduct({ shop, accessToken, productId }) {
const variables = {
id: `gid://shopify/Product/${productId}`
}
const response = await graphQLRequest({
shop,
accessToken,
query: GET_PRODUCT,
variables
});
return response;
}
graphQLRequest()
export default async function graphQLRequest({ shop, accessToken, query, variables }) {
try {
const url = `https://${shop}/admin/api/${ LATEST_API_VERSION }/graphql.json`;
const requestHeaders = {
'X-Shopify-Access-Token': accessToken,
}
const data = await request({
url,
document: query,
variables,
requestHeaders
})
return data;
} catch (error) {
console.log('error', error)
}
}
I'm using request() from the graphql-request client instead of GraphQLClient so that I can pass in variables (wasn't sure how to do this with GraphQLClient).
I'd love to hear if there's another way we're meant to be doing this that works.
That is very helpful.
I also have found another way auth the request and call Admin API using authenticate.public.appProxy (when the request coming through Proxy link from the shop frontend):
export async function action({ request }) {
....
const response = await authenticate.public.appProxy(request);
const responceGraphQL = await response.admin?.graphql(QUERY);
....
}
Discover how to increase the efficiency of commerce operations with Shopify Academy's l...
By Jacqui Mar 26, 2025Shopify and our financial partners regularly review and update verification requiremen...
By Jacqui Mar 14, 2025Unlock the potential of marketing on your business growth with Shopify Academy's late...
By Shopify Mar 12, 2025