# Handling Deep Links

Use handleDeepLink and campaign rules to present paywalls from deep links without hardcoding logic in your app.

When your app receives a deep link, you might be tempted to write a switch statement that maps each URL to a specific placement and calls `register`. This works, but it means every time you add a new link or change which paywall shows, you have to ship an app update.

A better approach is to pass the URL to `handleDeepLink` and let Superwall's [`deepLink_open`](/docs/dashboard/dashboard-campaigns/campaigns-standard-placements#deeplink_open) standard placement handle the rest. The SDK extracts the URL's path, query parameters, and other components, then fires `deepLink_open` as a placement. You write campaign rules on the dashboard to decide which paywall to show, which means there is no app update required.

The problem [#the-problem]

Here's a common pattern where deep link routing is hardcoded in the app:

:::expo
```typescript
function handleUrl(url: string) {
  const path = new URL(url).pathname;
  let placement: string | undefined;

  switch (path) {
    case "/promo":
      placement = "promoPlacement";
      break;
    case "/onboarding":
      placement = "onboardingPlacement";
      break;
    case "/upgrade":
      placement = "upgradePlacement";
      break;
    case "/special-offer":
      placement = "specialOfferPlacement";
      break;
  }

  if (placement) {
    superwall.register(placement);
  }
}
```
:::

Every new URL path means a code change, a build, and an app store review. If you want to change which paywall shows for `/promo`, that's another update too.

The solution: `handleDeepLink` + campaign rules [#the-solution-handledeeplink--campaign-rules]

Instead, pass the URL to `handleDeepLink`. The SDK fires the `deepLink_open` standard placement with all of the URL's components as parameters. Then, on the Superwall dashboard, you create campaign rules that match on those parameters to decide what to show.

:::expo
```typescript
function handleUrl(url: string) {
  SuperwallExpoModule.handleDeepLink(url);
}
```
:::

That's it on the app side. The routing logic lives on the dashboard.

Setting up campaign rules [#setting-up-campaign-rules]

Once `handleDeepLink` is wired up, the `deepLink_open` placement fires every time a deep link arrives. The URL's path, host, query parameters, and other components are available as parameters you can match against in your campaign's audience filters.

## Create a campaign

On the Superwall dashboard, create a new [campaign](/docs/dashboard/dashboard-campaigns/campaigns) — for example, "Deep Link Paywalls".

## Add the deepLink_open placement

In your campaign, [add a placement](/docs/dashboard/dashboard-campaigns/campaigns-placements#adding-a-placement) and select `deepLink_open` from the standard placements list.

## Add audience filters

Edit the default audience and add filters that match the URL components you care about. For example, if your deep link is `myapp://promo?offer=summer`:- Set `params.path` **is** `promo` to match the path.
- Set `params.offer` **is** `summer` to match the query parameter.See [`deepLink_open` parameters](/docs/dashboard/dashboard-campaigns/campaigns-standard-placements#deeplink_open) for the full list of available fields.

## Attach a paywall

Click **Paywalls** at the top of the campaign and choose which paywall to present when the filters match.



Now when a user opens `myapp://promo?offer=summer`, the SDK fires `deepLink_open`, the campaign rule matches, and the paywall shows. That's all without touching your app code. To add a new deep link path or change which paywall it shows, just update the campaign on the dashboard.

Multiple deep link routes [#multiple-deep-link-routes]

You can handle several deep link patterns from a single campaign by adding multiple audiences, each with its own filters and paywalls. For example:

| Deep link                     | Filter                                                   | Paywall         |
| ----------------------------- | -------------------------------------------------------- | --------------- |
| `myapp://promo?offer=summer`  | `params.path` is `promo` AND `params.offer` is `summer`  | Summer Sale     |
| `myapp://promo?offer=newyear` | `params.path` is `promo` AND `params.offer` is `newyear` | New Year Offer  |
| `myapp://upgrade`             | `params.path` is `upgrade`                               | Upgrade Paywall |

Each audience evaluates independently. When you need to add a new route, create a new audience on the dashboard — no app update needed.

Prerequisites [#prerequisites]

To use `handleDeepLink`, your app needs deep link handling set up first. If you haven't done that yet, follow the setup guide:

:::expo
* [Deep link setup](/docs/sdk/quickstart/in-app-paywall-previews)
:::

Related deep link guides [#related-deep-link-guides]

:::expo
* [Deep Link Setup](/docs/sdk/quickstart/in-app-paywall-previews) — Configure URL schemes, universal links, and wire `handleDeepLink` into your app so Superwall can respond to incoming links.
:::