Uninstall webhook not trigerring locally

Topic summary

A developer building a Shopify app with Remix is unable to trigger the app/uninstalled webhook in their local development environment. They want to update their database when merchants uninstall the app.

Current setup:

  • Webhook handler exists at /routes/webhooks.app.uninstalled.tsx
  • Webhook registered in shopify.app.toml with URI /webhooks/app/uninstalled
  • Using ngrok tunnel with --tunnel-url flag in dev command

Additional issue:
The Shopify CLI repeatedly overrides their shopify.app.toml configuration file (creating shopify.app.<APP_NAME>.toml), resetting custom scopes and webhook registrations to default values.

Suggested solutions:

  • Use --config flag with shopify app dev to specify configuration file, or run shopify app config use for existing configs
  • Webhooks often don’t trigger reliably in local environments despite ngrok providing HTTPS
  • Test webhooks locally using shopify app webhook trigger command to manually invoke them
  • Ensure app URL and settings are configured correctly

Status: The issue remains unresolved; the developer is seeking clarification on proper configuration management and webhook testing approaches.

Summarized with AI on October 26. AI used: claude-sonnet-4-5-20250929.

Hi,

I am a newbie in shopify. Just starting out and I tried to follow existing answers on this issue but, I am still failing.I have created this shopify app with remix and the problem is, when I uninstall the app, I want to update my db for the store that is uninstalling the app but, I am not able to do it since my uninstall webhook is not trigerring when the app is uninstalled.I have webhooks.app.uninstalled.tsx located under /routes/webhooks.app.uninstalled.tsx with the following boilerplate

import type { ActionFunctionArgs } from '@remix-run/node';
import { authenticate } from '../shopify.server';
import db from '../db.server';

export const action = async ({ request }: ActionFunctionArgs) => {
  console.log('webhooks.app.uninstalled.tsx loaded');
  const { shop, session, topic } = await authenticate.webhook(request);

  console.log(`Received ${topic} webhook for ${shop}`);

  // Webhook requests can trigger multiple times and after an app has already been uninstalled.
  // If this webhook already ran, the session may have been deleted previously.
  if (session) {
    await db.session.deleteMany({ where: { shop } });
  }

  return new Response();
};

I have unistall webhook registered under my shopify.app.toml


[webhooks]
api_version = "2025-07"

  [[webhooks.subscriptions]]
  topics = [ "app/scopes_update" ]
  uri = "/webhooks/app/scopes_update"

  [[webhooks.subscriptions]]
  topics = [ "app/uninstalled" ]
  uri = "/webhooks/app/uninstalled"

And I am using ngrok as tunnel url and configured my npm run dev command as
“dev”: “shopify app dev --tunnel-url=TUNNEL_URL:8080”,

Also, I am very confused about shopify.app.toml and when I install an app, shopify cli creates a new toml file with sopify.app.<APP_NAME>.toml and everytime it overrides the content of the toml file. Meaning, if I add new scopes, register new webhooks or anything, and want to update the app, it is always overridden with default values and it is extremely annoying. Can anyone please guide me through how to update my scopes and register webhooks properly without shopify CLI having to replace or override everything.

Thanks in advance.

Well would you like me to access your store backend and see if this could be solved it would be a good idea if we can do this together. And get it solved.

@Fatima24 What do you mean by getting access to my store’s backend? You would like to see the code? Or, would you like to connect and do it together?

Hi @Nabeel77
When you are running shopify app dev, you can pass a –config flag with this
like shopify app dev --config=yourconfig
OR
You can use shopify app config use to use the existing config

and for uninstall hook not working, it happens with local environment because webhook needs https url, since you are working with ngrok tunnel then it provides https url so well so please make sure you have setup app url and other settings correctly. uninstall and other hooks sometimes doesn’t work as expected on local environment.

You can use shopify app webhook trigger command to manually call webhook from local and test it

Thanks!

Hi @pawankumar, thank you so much for answering.

The first part of your answer is regarding the config overwrite I believe, yes?

I have ngrok url setup in my shopify.app..toml (This is set automatically by shopify cli when I run npm run dev – –reset). Is there any other place in my app I should set this ngrok tunnel url?

@Nabeel77

You can pass it on app dev command like below:

shopify app dev --tunnel-url=your-ngrok-tunnel-url

In this way, this tunnel will be used instead of shopify auto generated tunnel

Thanks!