How to return data from App proxy endpoint to Theme extension liquid

Topic summary

Issue Identified:
A developer encountered a 302 status code and no data return when creating an App proxy endpoint in a Remix template Shopify app, followed by an unexpected 404 login call.

Root Cause:
The problem stemmed from exporting a React component (<Page>Proxy</Page>) in the proxy endpoint file, which is unnecessary since app proxies render on the storefront, not in the admin panel.

Solution:

  • Remove the React component export and default export
  • Keep only the action or loader function
  • Remove the route declaration from app.tsx (the <Link to="/app/backend2"> reference)
  • Use only GET (loader) or POST (action) methods

Additional Guidance:
App proxies can combine backend queries with Liquid templating, which renders within the theme’s {{ content_for_layout }}. A code example demonstrates fetching product data via GraphQL and returning it using the liquid() helper function, allowing the response to display with the theme’s header and footer.

Status: Resolved with community clarification provided.

Summarized with AI on November 1. AI used: claude-sonnet-4-5-20250929.

Hey guys, so i just created an App proxy endpoint in my remix template App and im able to receive data, but im not understandting how to return data. I get status code 302 on the response, and nothing is returned. Also its followed by a 404 login call, that im not sure what it is.

I have my proxy enpoind defined in app.tsx

Backend endpoint

and the service is this

export const action: ActionFunction = async ({ request }) => {
console.log(“-----hit app proxy---------------”);

const { session } = await authenticate.public.appProxy(request);
if (session) {
console.log(“response”, session);
}
return json({ message: “success” });
};

const Proxy = () => {
return Proxy;
};

export default Proxy;

any ideas what im doing wrong

ok, how?..

nevermind my bad, i just had to erase the part where it returns a html component

const Proxy = () => {
return Proxy;
};

export default Proxy;

and just left the action function in the file, and now its returning the response

2 Likes

It’s already solved but I’ll leave the comment to complement the solution.

When using the Shopify proxy it is not necessary to export a view in Polaris because it is not rendered in the admin panel but in the client.

Therefore you must remove the following:

const Proxy = () => {
  return ;
};

export default Proxy;

And there is no need to declare the route in app.tsx either. You should remove it as well.

Backend endpoint

The only methods that work are GET (loader) and POST (action).

Remember that you can combine a query to your backend and liquid.

Liquid will be rendered in your theme’s {{ content_for_layout }}, so you will be able to see the theme’s header and footer.

import shopify from "../shopify.server";

export async function loader({ request }) {
  const { admin, liquid } = await shopify.authenticate.public.appProxy(request);

  const response = await admin.graphql(
    `#graphql
    query productTitle {
      products(first: 1) {
        nodes {
          title
        }
      }
    }`,
  );
  const body = await response.json();
  const title = body.data.products.nodes[0].title;

  return liquid(
    `
    `,
  );
}

export async function action({ request }) {
  const { admin } = await shopify.authenticate.public.appProxy(request);
  // Your POST code...
  return null;
}

Puede consultar la documentación completa en:

https://shopify.dev/docs/api/shopify-app-remix/v3/authenticate/public/app-proxy

Result: