Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to redirect to a resource in Shopify Admin #2166

Open
nboliver-ventureweb opened this issue Feb 28, 2025 · 4 comments
Open

How to redirect to a resource in Shopify Admin #2166

nboliver-ventureweb opened this issue Feb 28, 2025 · 4 comments

Comments

@nboliver-ventureweb
Copy link

nboliver-ventureweb commented Feb 28, 2025

Using the redirect function returned from authenticate.admin, it does not seem possible to redirect to a resource in the Shopify Admin (outside the embedded app).

Example use case in an action:

export const action = async ({ request, params }: ActionFunctionArgs) => {
  const { admin, redirect } = await authenticate.admin(request);
  ...
  return redirect('shopify://admin/discounts');
});

This example doesn't work, and the current route just reloads. How can this be achieved?

There is another old issue on this topic (#705), but it does not answer the question of redirecting to a resource in the admin, only to an external URL or an app route.

@lizkenyon
Copy link
Contributor

Hi there 👋

I am not able to reproduce your issue. Here was my code

export const action = async ({ request }) => {
  const { admin, redirect } = await authenticate.admin(request);

  return redirect("shopify://admin/discounts");
...
screencast.2025-03-03.09-25-37.mp4

Do you have any remix future flags enabled? Otherwise could you provide minimal repository to reproduce your issue, if you would like us to look any further into this?

@nboliver-ventureweb
Copy link
Author

nboliver-ventureweb commented Mar 3, 2025

@lizkenyon Thanks for the reply - we don't have future flags enabled, and it appears as though the issue is being caused by the redirect being wrapped in a try/catch block. Without the try/catch, it works as expected. However, once the redirect is added to the try, the following response is being caught, which seems to be triggering the route's loader:

    try {
      return redirect('shopify://admin/discounts');
    } catch (error) {
      return actionErrorResponse(error, 'Failed to delete discount');
    }

Image

Not sure if this could be related, but we have made some customizations to the ErrorBoundary in app.tsx:

export function ErrorBoundary() {
  const error = useRouteError();

  if (isRouteErrorResponse(error)) {
    const { status, statusText, data } = error;
    const message = data?.error || statusText;
    return <ErrorPage status={status} message={message} />;
  } else {
    try {
      // Catch redirect Response thrown by @shopify/shopify-app-remix
      const shopifyError = boundary.error(error);
      return shopifyError;
    } catch (error) {
      const message =
        error instanceof Error ? error.message : 'An unknown error occurred';
      return <ErrorPage status={500} heading="Error" message={message} />;
    }
  }
}

@lizkenyon
Copy link
Contributor

Yes, this is expected behaviour.

This code should work

export const action = async ({ request }: ActionFunctionArgs) => {
  const { admin, redirect } = await authenticate.admin(request);
  try {
    return redirect('shopify://admin/discounts');
  } catch (error) {
    if (error instanceof Response) {
      throw error;
    }
    console.log('failed to redirect', error);
  }

The shopify remix package throws the 401 response, and App Bridge does the redirecting.

I am going to move into our backlog to better document this.

@nboliver-ventureweb
Copy link
Author

Thanks, that does the trick. It would be great to have more explicit documentation about customizing the ErrorBoundary. I was able to cobble it together by finding a few old issues relating to it, but it was definitely not clear what the recommended approach was with respect to the customizations the Shopify Remix package makes beyond a standard Remix implementation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants