Hey I am creating a shopify hydrogen app and currently want ot login form my local app. Unfortunaelty it shows up the mentioned error in the image. Looks like it redirects me to my account page where the error is being trigerred by remix loaders.
Anyone has ever experienced integrating user auth flow in hydrogen app.
This is the link that the error page loads:
https://shopify.com/authentication/60802433076/oauth/authorize?client_id=shp_429055a5-1cf3-4e9f-ad61-12b3e500bb88&scope=openid+email+customer-account-api%3Afull&response_type=code&redirect_uri=https%3A%2F%2Flocalhost%3A3000%2Faccount%2Fauthorize&state=17461138725200jlntbybumyl&nonce=b425f3e8d060200f5a50ac090c0d3873&ui_locales=en&code_challenge=q9aWPaLCVppf9xXuqGqvSU22INLa9B5NizHQeScjPIk&code_challenge_method=S256
The following is my routes structure of account files:
Create an .env file if you haven’t already:
env
CopyEdit
PUBLIC_APP_URL=http://localhost:3000 SHOPIFY_APP_API_KEY=your_api_key_here SHOPIFY_APP_SECRET=your_secret_here
In your app code:
ts
CopyEdit
const REDIRECT_URI = ${process.env.PUBLIC_APP_URL}/auth/callback;
2. Route: app/routes/auth._authorize.tsx
Use this route to initiate OAuth:
tsx
CopyEdit
// app/routes/auth._authorize.tsx import { LoaderFunction, redirect } from “@remix-run/node”; export const loader: LoaderFunction = async ({ request }) => { const shop = new URL(request.url).searchParams.get(“shop”); if (!shop) { return new Response(“Missing shop parameter”, { status: 400 }); } const redirectUri = ${process.env.PUBLIC_APP_URL}/auth/callback; const oauthUrl = https://${shop}/admin/oauth/authorize?client_id=${process.env.SHOPIFY_APP_API_KEY}&scope=read_products,write_orders&redirect_uri=${encodeURIComponent( redirectUri )}&state=noncevalue&grant_options[]=per-user; return redirect(oauthUrl); };
3. Route: app/routes/auth.callback.tsx
This is where Shopify redirects after OAuth — here you handle the token exchange:
tsx
CopyEdit
// app/routes/auth.callback.tsx import { LoaderFunction, redirect } from “@remix-run/node”; export const loader: LoaderFunction = async ({ request }) => { const url = new URL(request.url); const shop = url.searchParams.get(“shop”); const code = url.searchParams.get(“code”); if (!shop || !code) { return new Response(“Invalid callback params”, { status: 400 }); } // Exchange code for token or do what your app needs here // Redirect to account or dashboard after successful auth return redirect(“/account”); };
Bonus: Protect account._index.tsx Loader
Make sure your account._index.tsx loader checks that the user is authenticated before rendering:
tsx
CopyEdit
// app/routes/account._index.tsx import { LoaderFunction, redirect } from “@remix-run/node”; export const loader: LoaderFunction = async ({ request }) => { // Example: Check for session/token const user = await getUserFromSession(request); if (!user) { return redirect(“/auth/authorize?shop=myshop.myshopify.com”); } return { user }; };
Where exactly I should put the following:
const REDIRECT_URI = ${process.env.PUBLIC_APP_URL}/auth/callback;
Thanks for the hint, it worked.