<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/django-serve-apple-app-site-association-and-assetlinks-json-gfshatk6j" -->

---
title: Django: serve apple-app-site-association and assetlinks.json
description: A step-by-step walkthrough shows how to serve the apple-app-site-association and assetlinks.json files from Django so that links to a site open in companion...
canonical: https://daily.dev/posts/django-serve-apple-app-site-association-and-assetlinks-json-gfshatk6j
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Django: serve apple-app-site-association and assetlinks.json | daily.dev
og:description: A step-by-step walkthrough shows how to serve the apple-app-site-association and assetlinks.json files from Django so that links to a site open in companion...
og:url: https://daily.dev/posts/django-serve-apple-app-site-association-and-assetlinks-json-gfshatk6j
og:image: https://api.daily.dev/og/posts/GFShATK6j.png
og:image:alt: Django: serve apple-app-site-association and assetlinks.json
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Django: serve apple-app-site-association and assetlinks.json

**[Adam Johnson](https://daily.dev/sources/adamj)** · 7 min read · 0 upvotes · 1 comments

## Summary

A step-by-step walkthrough shows how to serve the apple-app-site-association and assetlinks.json files from Django so that links to a site open in companion iOS/Android apps (Universal Links and App Links). It covers writing both JSON files, creating Django views with login_not_required, require_safe, and cache_control decorators, wiring up URLconf entries, writing SimpleTestCase tests to catch silent JSON errors, and verifying the setup in production via Apple's CDN and Google's Digital Asset Links API.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://adamj.eu/tech/2026/10/02/django-app-links>

## Questions this post answers

### How do I serve the apple-app-site-association file correctly from Django?

Save the file as apple-app-site-association.json next to your views, then serve it with a view using FileResponse so Django infers the application/json content type from the extension, while the URL path itself omits the .json extension. Decorate the view with @login_not_required, @require_safe, and @cache_control(max_age=300, public) so it returns a plain 200 OK with no redirect, required by Apple's verification system.

_daily.dev surfaces practical Django patterns like this for teams wiring up app links and passkeys._

### Why does my Universal Links or App Links setup silently fail even though the JSON file looks fine?

A malformed JSON file, such as one with a trailing comma, causes links to silently fall back to opening in the browser with no error message anywhere, since both Apple and Android fail silently on bad association files. Writing tests that parse the response body with json.loads() catches syntax errors before deployment, and checking the CDN or Digital Asset Links API after deploying confirms the platforms actually picked up the file.

_developers debugging flaky app-link behavior can track Django and mobile integration gotchas on daily.dev._

### How do I verify Apple or Google actually see my updated apple-app-site-association or assetlinks.json file after deployment?

For Apple, query the CDN directly with curl https://app-site-association.cdn-apple.com/a/v1/example.com since iOS 14+ and macOS 11+ fetch from Apple's CDN rather than your site, and the CDN can lag behind changes. For Android, use Google's Digital Asset Links API endpoint digitalassetlinks.googleapis.com/v1/statements:list or the Statement List Generator and Tester web tool, plus adb shell pm verify-app-links on a device.

_daily.dev helps developers shipping mobile deep-link integrations stay on top of platform verification steps._

## Community discussion

Top comments from developers on daily.dev.

**@nark3d** · 0 upvotes

> I'm going to set this up on a site I maintain, because the failure mode is genuinely nasty: no error, no log line, the link just opens in the browser and you find out from a user.  SimpleTestCase around the two JSON files is cheap.  It catches a stray comma or a wrong team ID before it ever ships.  Test the parsed structure rather than the response code, since that catches it before it ships.  https://prickles.org/tenet/behaviour-testing/TS6

## Similar posts on daily.dev

- [Django: serve a security.txt file](https://daily.dev/posts/django-serve-a-security-txt-file-czhcqnylj) · Adam Johnson · 0 upvotes · 0 comments
- [Secure File Upload System](https://daily.dev/posts/secure-file-upload-system-kwux4arbu) · Medium · 0 upvotes · 0 comments
- [How to Serve a Website With FastAPI Using HTML and Jinja2 – Real Python](https://daily.dev/posts/how-to-serve-a-website-with-fastapi-using-html-and-jinja2-real-python-oqqvfwmfy) · Real Python · 2 upvotes · 0 comments
- [Using Vite with Vue and Django](https://daily.dev/posts/using-vite-with-vue-and-django-4idcin01g) · Planet Python · 3 upvotes · 0 comments
- [Django integration testing](https://daily.dev/posts/django-integration-testing-l7tstkltm) · Honeybadger · 1 upvotes · 0 comments

---

Tags: [#python](https://daily.dev/tags/python), [#testing](https://daily.dev/tags/testing), [#django](https://daily.dev/tags/django)

[View this post on daily.dev](https://daily.dev/posts/django-serve-apple-app-site-association-and-assetlinks-json-gfshatk6j)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"Django: serve apple-app-site-association and assetlinks.json","url":"https://daily.dev/posts/django-serve-apple-app-site-association-and-assetlinks-json-gfshatk6j","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/django-serve-apple-app-site-association-and-assetlinks-json-gfshatk6j"},"datePublished":"2026-10-01T23:38:27.066Z","dateModified":"2026-10-01T23:38:51.587Z","description":"A step-by-step walkthrough shows how to serve the apple-app-site-association and assetlinks.json files from Django so that links to a site open in companion...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/96f94966e3f7c649fb94146cda61e8a0?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/96f94966e3f7c649fb94146cda61e8a0?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"Adam Johnson","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Adam Johnson","logo":"https://media.daily.dev/image/upload/t_logo,f_auto/v1/logos/bf70f4401c284aa5b628d1966029342c","url":"https://daily.dev/sources/adamj"},"commentCount":1,"discussionUrl":"https://daily.dev/posts/django-serve-apple-app-site-association-and-assetlinks-json-gfshatk6j","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":0},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":1}],"keywords":"python,testing,django","timeRequired":"PT7M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Adam Johnson","item":"https://daily.dev/sources/adamj"},{"@type":"ListItem","position":3,"name":"Django: serve apple-app-site-association and assetlinks.json"}]}
{"@context":"https://schema.org","@type":"WebPage","@id":"https://daily.dev/posts/django-serve-apple-app-site-association-and-assetlinks-json-gfshatk6j","comment":[{"@type":"Comment","text":"I’m going to set this up on a site I maintain, because the failure mode is genuinely nasty: no error, no log line, the link just opens in the browser and you find out from a user.  SimpleTestCase around the two JSON files is cheap.  It catches a stray comma or a wrong team ID before it ever ships.  Test the parsed structure rather than the response code, since that catches it before it ships.  https://prickles.org/tenet/behaviour-testing/TS6","datePublished":"2026-10-04T16:24:11.451Z","url":"https://daily.dev/posts/GFShATK6j#c-jOmA4FATI","author":{"@type":"Person","name":"Adam","url":"https://daily.dev/nark3d","image":"https://avatars.githubusercontent.com/u/2162621?v=4"}}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/django-serve-apple-app-site-association-and-assetlinks-json-gfshatk6j#faq","mainEntity":[{"@type":"Question","name":"How do I serve the apple-app-site-association file correctly from Django?","acceptedAnswer":{"@type":"Answer","text":"Save the file as apple-app-site-association.json next to your views, then serve it with a view using FileResponse so Django infers the application/json content type from the extension, while the URL path itself omits the .json extension. Decorate the view with @login_not_required, @require_safe, and @cache_control(max_age=300, public) so it returns a plain 200 OK with no redirect, required by Apple's verification system. daily.dev surfaces practical Django patterns like this for teams wiring up app links and passkeys."}},{"@type":"Question","name":"Why does my Universal Links or App Links setup silently fail even though the JSON file looks fine?","acceptedAnswer":{"@type":"Answer","text":"A malformed JSON file, such as one with a trailing comma, causes links to silently fall back to opening in the browser with no error message anywhere, since both Apple and Android fail silently on bad association files. Writing tests that parse the response body with json.loads() catches syntax errors before deployment, and checking the CDN or Digital Asset Links API after deploying confirms the platforms actually picked up the file. developers debugging flaky app-link behavior can track Django and mobile integration gotchas on daily.dev."}},{"@type":"Question","name":"How do I verify Apple or Google actually see my updated apple-app-site-association or assetlinks.json file after deployment?","acceptedAnswer":{"@type":"Answer","text":"For Apple, query the CDN directly with curl https://app-site-association.cdn-apple.com/a/v1/example.com since iOS 14+ and macOS 11+ fetch from Apple's CDN rather than your site, and the CDN can lag behind changes. For Android, use Google's Digital Asset Links API endpoint digitalassetlinks.googleapis.com/v1/statements:list or the Statement List Generator and Tester web tool, plus adb shell pm verify-app-links on a device. daily.dev helps developers shipping mobile deep-link integrations stay on top of platform verification steps."}}]}
```

