Webhooks are a great mechanism for the communication between applications. However, 404 failures when setting up webhooks in a Remix application can be a real pain. This guide will explain the common causes leading to these errors and how to resolve them successfully.

Understanding Webhook 404 Errors
A 404 error happens when the source system of the webhook is trying to access the application endpoint but could not find it. Common causes for this are the following:
- Wrong Endpoint URL: The URL you provided to the source system of the webhook was founded faulty or doesn’t exist.
- Route Not Configured in Remix: The route does not exist or is not configured properly for the webhook.
- Authentication Issues: If the endpoint requires authentication, failure to provide valid credentials results in a 404 error.
Steps to Fix 404 Errors
Step 1: Configuring the Route in Remix
Create route files under routes to handle incoming webhook events.
Route: webhooks.app.uninstalled.jsx
import { json } from '@remix-run/node';
export const action = async ({ request }) =>
const { shop, session, topic } = await authenticate.webhook(request);
console.log(`App Uninstalled: ${shop}`);
if (session) {
await db.session.deleteMany({ where: { shop } });
}
return new Response();
};
Route: webhooks.customers.data_request.jsx
import { json } from '@remix-run/node';
export const action = async ({ request }) => {
const { shop, payload, topic } = await authenticate.webhook(request);
console.log('Customer Data Request:', payload);
console.log(JSON.stringify(payload, null, 2));
return new Response();
};
Route: webhooks.customers.redact.jsx
import { json } from '@remix-run/node';
export const action = async ({ request }) => {
const { shop, payload, topic } = await authenticate.webhook(request);
console.log('Customer Redact Request:', payload);
console.log(JSON.stringify(payload, null, 2));
return new Response();
};
Route: webhooks.shop.redact.jsx
import { json } from '@remix-run/node';
export const action = async ({ request }) => {
const { shop, payload, topic } = await authenticate.webhook(request);
console.log('Shop Redact Request:', payload);
console.log(JSON.stringify(payload, null, 2));
return new Response();
};

Step 2: Verify Your Webhook Configuration
Ensure the webhook setup in your Shopify server file matches your intended routes. For example:
Route: shopify.server.js
webhooks: {
APP_UNINSTALLED: {
deliveryMethod: DeliveryMethod.Http,
callbackUrl: '/webhooks/app/uninstalled',
},
CUSTOMERS_DATA_REQUEST: {
deliveryMethod: DeliveryMethod.Http,
callbackUrl: '/webhooks/customers/data_request',
},
CUSTOMERS_REDACT: {
deliveryMethod: DeliveryMethod.Http,
callbackUrl: '/webhooks/customers/redact',
},
SHOP_REDACT: {
deliveryMethod: DeliveryMethod.Http,
callbackUrl: '/webhooks/shop/redact',
},
},
Match these callback URLs to their corresponding routes in your Remix application.
Step 3: Match Shopify Configuration with Routes
Map the URLs for your webhooks to align with the Remix routes of your Shopify app in its configuration:
- Customer data request endpoint: https://{app_url}/webhooks/customers/data_request
- Customer data erasure endpoint: https://{app_url}/webhooks/customers/redact
- Shop data erasure endpoint: https://{app_url}/webhooks/shop/redact
Step 4: Deploy and Verify
After following the above procedure, deploy your application and check:
- Requests from the webhook are indeed going to the correct endpoints.
- The logs verify the correct payload is being received.

Conclusion
If you follow the guide above, your Remix application should be processing webhooks with no issues at all, hitting no 404 errors. The route configuration should be correct, you are checking your logs, and any testing will ensure that the integration has been successful.