Skip to content
Tolinku
Tolinku
Sign In Start Free
Marketing · · 7 min read

Getting App Content into Search Results

By Tolinku Staff
|
Tolinku seo app indexing dashboard screenshot for marketing blog posts

Your app contains content that users search for every day: products, articles, recipes, videos, listings, profiles. But search engines cannot crawl your app the way they crawl websites. Without explicit setup, your in-app content is invisible to Google and Apple search.

Getting your app content into search results requires three things: deep links that connect web URLs to in-app destinations, verification files that prove your app owns those URLs, and markup that tells search engines about the relationship. This guide covers all three. For platform-specific setup, see Google App Indexing and Apple Spotlight indexing.

The Web-App Connection

Search engines index web pages, not app screens. To get app content into search results, you need to establish a connection between your web pages and your app:

Web page: https://www.yourapp.com/products/123
    ↓ (connected via deep link markup + verification)
App screen: ProductActivity showing product 123

When a user on a mobile device clicks a search result that has this connection, the search engine can open the app directly instead of loading the web page. This is better for the user (faster, native experience) and better for you (higher engagement, lower bounce rate).

What You Need

  1. Web pages for your content. Every piece of app content that you want in search results needs a corresponding web URL. This does not need to be a full web app; even a simple server-rendered page works.

    Deep link handling in your app. Your app must handle incoming URLs and route users to the correct content. On Android, this means App Links. On iOS, this means Universal Links.

    Verification files. Your website must host verification files that prove your app is authorized to handle your URLs:

    • Android: /.well-known/assetlinks.json
    • iOS: /.well-known/apple-app-site-association

    Search markup. Your web pages need markup that tells search engines about the app connection.

    Structured Data for App Indexing

    Structured data tells search engines about your content in a machine-readable format. For app indexing, use the potentialAction property to declare that your content can be viewed in an app.

    ViewAction Markup

    <script type="application/ld+json">
    {
      "@context": "https://schema.org",
      "@type": "WebPage",
      "name": "Summer Sale Collection",
      "url": "https://www.yourapp.com/collections/summer-sale",
      "potentialAction": {
        "@type": "ViewAction",
        "target": [
          "https://www.yourapp.com/collections/summer-sale",
          {
            "@type": "EntryPoint",
            "urlTemplate": "android-app://com.yourapp.android/https/www.yourapp.com/collections/summer-sale"
          }
        ]
      }
    }
    </script>
    

    Content-Specific Markup

    Different content types have different structured data requirements:

    Products:

    <script type="application/ld+json">
    {
      "@context": "https://schema.org",
      "@type": "Product",
      "name": "Running Shoes Model X",
      "description": "Lightweight running shoes for road and trail",
      "image": "https://www.yourapp.com/images/shoes-x.jpg",
      "offers": {
        "@type": "Offer",
        "price": "129.99",
        "priceCurrency": "USD"
      },
      "potentialAction": {
        "@type": "ViewAction",
        "target": "https://www.yourapp.com/products/shoes-x"
      }
    }
    </script>
    

    Articles:

    <script type="application/ld+json">
    {
      "@context": "https://schema.org",
      "@type": "Article",
      "headline": "10 Best Running Routes in San Francisco",
      "author": { "@type": "Person", "name": "Jane Smith" },
      "datePublished": "2026-01-15",
      "potentialAction": {
        "@type": "ViewAction",
        "target": "https://www.yourapp.com/articles/sf-running-routes"
      }
    }
    </script>
    

    Recipes:

    <script type="application/ld+json">
    {
      "@context": "https://schema.org",
      "@type": "Recipe",
      "name": "Classic Margherita Pizza",
      "cookTime": "PT25M",
      "recipeYield": "4 servings",
      "potentialAction": {
        "@type": "ViewAction",
        "target": "https://www.yourapp.com/recipes/margherita-pizza"
      }
    }
    </script>
    

    In addition to structured data, add <link> elements in your HTML <head> that declare app alternatives:

    <head>
      <!-- Android App Link -->
      <link rel="alternate" href="android-app://com.yourapp.android/https/www.yourapp.com/products/123" />
    
      <!-- iOS Smart App Banner -->
      <meta name="apple-itunes-app" content="app-id=YOUR_APP_STORE_ID, app-argument=https://www.yourapp.com/products/123">
    </head>
    

    The alternate link tells Google that an Android app can display this content. The Smart App Banner meta tag tells Safari that an iOS app is available.

    Sitemap Integration

    For sites with many indexable pages, add app deep link annotations to your XML sitemap:

    <?xml version="1.0" encoding="UTF-8"?>
    <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
            xmlns:xhtml="http://www.w3.org/1999/xhtml">
      <url>
        <loc>https://www.yourapp.com/products/123</loc>
        <lastmod>2026-01-15</lastmod>
        <xhtml:link rel="alternate"
                    href="android-app://com.yourapp.android/https/www.yourapp.com/products/123" />
      </url>
      <url>
        <loc>https://www.yourapp.com/products/456</loc>
        <lastmod>2026-01-14</lastmod>
        <xhtml:link rel="alternate"
                    href="android-app://com.yourapp.android/https/www.yourapp.com/products/456" />
      </url>
    </urlset>
    

    This is especially useful for e-commerce apps with thousands of product pages. Generate the sitemap programmatically:

    function generateSitemap(products) {
      let xml = '<?xml version="1.0" encoding="UTF-8"?>\n';
      xml += '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"\n';
      xml += '        xmlns:xhtml="http://www.w3.org/1999/xhtml">\n';
    
      for (const product of products) {
        const webUrl = `https://www.yourapp.com/products/${product.slug}`;
        const appUrl = `android-app://com.yourapp.android/https/www.yourapp.com/products/${product.slug}`;
    
        xml += '  <url>\n';
        xml += `    <loc>${webUrl}</loc>\n`;
        xml += `    <lastmod>${product.updatedAt}</lastmod>\n`;
        xml += `    <xhtml:link rel="alternate" href="${appUrl}" />\n`;
        xml += '  </url>\n';
      }
    
      xml += '</urlset>';
      return xml;
    }
    

    Content Parity Requirements

    Both Google and Apple require that your app content matches your web content. If a user clicks a search result and opens your app, the app must show the same content (or richer content) as the web page.

    Violations that can get your app results removed:

    • App shows login wall. The user clicks a search result, the app opens, and immediately shows a login screen instead of the content. Search engines consider this a bad experience.
    • App shows different content. The web page shows product details, but the app shows a homepage or a generic landing page.
    • App crashes. If the deep link causes a crash, search engines will stop showing app results for that URL.
    • App not installed. If there is no fallback for users without the app, the result is useless. Always provide a web fallback.

    Handling Users Without the App

    When a user clicks an app-indexed search result but does not have the app installed:

    • Android: The browser loads the web page (assuming you have autoVerify set). Google may show an "Install" button.
    • iOS: Safari loads the web page. Your Smart App Banner encourages installation.

    Your web pages must work as standalone content, not just as wrappers for the app.

    Measuring Search Performance

    Google Search Console

    In Google Search Console, filter the Performance report by "App" to see:

    • Impressions: How often your app results appear in search.
    • Clicks: How often users tap your app results.
    • CTR: Click-through rate for app results vs. web results.
    • Queries: What users are searching for when they find your app content.

    Key Metrics to Track

    Metric What It Tells You
    App impressions How much of your content is indexed
    App click-through rate How appealing your app results are
    Post-click engagement Whether app content matches user intent
    Install rate from search How effective search is as an acquisition channel

    Common Pitfalls

    1. No web equivalent. If your content only exists in the app (no web URL), it cannot appear in search results. You need web pages.

      Inconsistent URL structure. If your web URLs use one pattern (/product?id=123) and your app expects another (/products/123), the mapping breaks. Standardize on one URL structure.

      Verification file errors. The most common failure. assetlinks.json or apple-app-site-association has a typo, wrong fingerprint, or is not served with the correct Content-Type header.

      Ignoring deep link testing. Structured data passes validation, but the actual deep link does not work in the app. Always test the full flow: search result, app open, content display.

      Thin web pages. Creating empty web pages just to have URLs for app indexing. Google will flag these as thin content and may penalize your entire site.

      Tolinku provides the deep link routing and verification file hosting that app indexing depends on. Configure your routes and domain in the Tolinku dashboard, and Tolinku handles serving assetlinks.json and apple-app-site-association automatically.

      For app packs in search results, see app packs in SERPs. For the broader strategy, see app indexing and SEO for mobile apps.

Get deep linking tips in your inbox

One email per week. No spam.

Ready to add deep linking to your app?

Set up Universal Links, App Links, deferred deep linking, and analytics in minutes. Free to start.