How to Configure the Server for Content-Type: application/json
Since the file has no extension, most web servers won't automatically know it's JSON. You need to explicitly tell the server to use the application/json
MIME type for this specific file path.
Here's how to do it on common web servers:
1. Apache:
You can configure this using either an .htaccess
file in the relevant directory (root or .well-known
) or directly in your Apache server/virtual host configuration files (httpd.conf
, apache2.conf
, or site-specific .conf
files).
-
Using
.htaccess
or Server Config (Recommended Method): Place this directive within your.htaccess
file (ensureAllowOverride FileInfo
orAllowOverride All
is enabled for the directory) or inside a<Directory>
or<Location>
block in your main configuration:# For the root directory <Files "apple-app-site-association"> ForceType application/json </Files> # Or, if placing it in .well-known <Directory "/path/to/your/public_html/.well-known"> <Files "apple-app-site-association"> ForceType application/json </Files> </Directory> # Alternative using Location (matches the URL path) <Location "/apple-app-site-association"> ForceType application/json </Location> # Or <Location "/.well-known/apple-app-site-association"> ForceType application/json </Location>
The
ForceType
directive explicitly sets the MIME type for the matched file(s), overriding other rules. -
Restart/Reload Apache: After modifying configuration files (not
.htaccess
), you need to reload or restart Apache for the changes to take effect (e.g.,sudo systemctl reload apache2
orsudo service apache2 reload
).
2. Nginx:
Edit your Nginx server block configuration (usually found in /etc/nginx/sites-available/yourdomain.conf
or similar). Add a specific location
block for the AASA file path.
-
Inside your
server { ... }
block:server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name yourdomain.com; # ... other SSL settings, root directory etc ... root /path/to/your/public_html; # Option 1: Exact match for root location location = /apple-app-site-association { default_type application/json; } # Option 2: Exact match for .well-known location location = /.well-known/apple-app-site-association { default_type application/json; } # ... other location blocks ... }
The
location = /path
provides an exact match for the URL.default_type application/json;
tells Nginx to serve files matching this location with the specified Content-Type. -
Alternatively, using the
types
directive (less common for exact file matches but works):# Inside the location block for /.well-known/ or / location = /apple-app-site-association { types { application/json; } } # Or location = /.well-known/apple-app-site-association { types { application/json; } }
-
Reload Nginx: After saving the configuration file, test it (
sudo nginx -t
) and then reload Nginx (sudo systemctl reload nginx
orsudo service nginx reload
).
3. Other Environments (CDNs, Static Hosting, Cloud Storage):
- Content Delivery Networks (CDNs - Cloudflare, Akamai, Fastly, etc.): Most CDNs either pass through the
Content-Type
header set by your origin server or provide a way to set/override headers based on the URL path using edge rules or configuration settings. Check your CDN provider's documentation for "MIME types" or "custom headers". - Static Hosting Platforms (Netlify, Vercel, Firebase Hosting, GitHub Pages):
- Netlify: Use a
_headers
file ornetlify.toml
.# _headers example /apple-app-site-association Content-Type: application/json /.well-known/apple-app-site-association Content-Type: application/json
- Vercel: Use a
vercel.json
file.{ "headers": [ { "source": "/apple-app-site-association", "headers": [{ "key": "Content-Type", "value": "application/json" }] }, { "source": "/.well-known/apple-app-site-association", "headers": [{ "key": "Content-Type", "value": "application/json" }] } ] }
- Firebase Hosting: Use the
headers
section infirebase.json
.{ "hosting": { "headers": [ { "source": "/apple-app-site-association", "headers": [{ "key": "Content-Type", "value": "application/json" }] }, { "source": "/.well-known/apple-app-site-association", "headers": [{ "key": "Content-Type", "value": "application/json" }] } ] } }
- GitHub Pages: Serving extensionless files with specific content types can be tricky. Placing the file in the
.well-known
directory might automatically get the correct content type from GitHub Pages if the content is valid JSON, but it's less guaranteed than explicit configuration. Check their documentation or consider using a build process with GitHub Actions if needed.
- Netlify: Use a
- Cloud Storage (AWS S3, Google Cloud Storage): When uploading the
apple-app-site-association
file to your bucket, you must explicitly set theContent-Type
metadata for the object toapplication/json
. If serving directly from the storage bucket (or via CloudFront/Cloud CDN), ensure this metadata is set correctly.
Validation Steps:
-
Upload: Place the
apple-app-site-association
file (with valid JSON content) in the chosen location (/
or/.well-known/
) on your server. -
Configure: Apply the server configuration changes (Apache/Nginx/Platform specific) as described above.
-
Reload/Deploy: Reload your web server or deploy your changes if using a static hosting platform.
-
Test with
curl
: Use the command line toolcurl
to check the headers. Replaceyourdomain.com
with your actual domain.curl -v https://yourdomain.com/apple-app-site-association # OR curl -v https://yourdomain.com/.well-known/apple-app-site-association
In the output (lines starting with
<
), look for:< HTTP/2 200
(or< HTTP/1.1 200 OK
) - Indicates the file was found.< content-type: application/json
- Confirms the correct header is being sent.- Ensure there are no redirect headers like
< Location: ...
-
Use an Online Validator: Search for "AASA validator" online. Many tools allow you to enter your domain, and they will check if the file is accessible, served over HTTPS, has the correct content type, and contains valid JSON. Apple also provides some validation resources.
-
Test on Device: The ultimate test is to install your app build (associated with the domain) on a physical iOS device and click a link that matches a path defined in your AASA file. It should open the app directly (if installed) instead of Safari.
By following these steps and correctly configuring your server to send the Content-Type: application/json
header, you ensure that iOS can correctly fetch, parse, and trust your AASA file for enabling Universal Links.
<Location "/apple-app-site-association"> ForceType application/json
<Location "/.well-known/apple-app-site-association"> ForceType application/json The ForceType directive explicitly sets the MIME type for the matched file(s), overriding other rules.
Restart/Reload Apache: After modifying configuration files (not .htaccess), you need to reload or restart Apache for the changes to take effect (e.g., sudo systemctl reload apache2 or sudo service apache2 reload).
- Nginx:
Edit your Nginx server block configuration (usually found in /etc/nginx/sites-available/yourdomain.conf or similar). Add a specific location block for the AASA file path.
Inside your server { ... } block:
Nginx
server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name yourdomain.com;
# ... other SSL settings, root directory etc ...
root /path/to/your/public_html;
# Option 1: Exact match for root location
location = /apple-app-site-association {
default_type application/json;
}
# Option 2: Exact match for .well-known location
location = /.well-known/apple-app-site-association {
default_type application/json;
}
# ... other location blocks ...
} The location = /path provides an exact match for the URL. default_type application/json; tells Nginx to serve files matching this location with the specified Content-Type.
Alternatively, using the types directive (less common for exact file matches but works):
Nginx
location = /apple-app-site-association { types { application/json; } }
location = /.well-known/apple-app-site-association { types { application/json; } } Reload Nginx: After saving the configuration file, test it (sudo nginx -t) and then reload Nginx (sudo systemctl reload nginx or sudo service nginx reload).
- Other Environments (CDNs, Static Hosting, Cloud Storage):
Content Delivery Networks (CDNs - Cloudflare, Akamai, Fastly, etc.): Most CDNs either pass through the Content-Type header set by your origin server or provide a way to set/override headers based on the URL path using edge rules or configuration settings. Check your CDN provider's documentation for "MIME types" or "custom headers". Static Hosting Platforms (Netlify, Vercel, Firebase Hosting, GitHub Pages): Netlify: Use a _headers file or netlify.toml.
/apple-app-site-association Content-Type: application/json /.well-known/apple-app-site-association Content-Type: application/json Vercel: Use a vercel.json file. JSON
{ "headers": [ { "source": "/apple-app-site-association", "headers": [{ "key": "Content-Type", "value": "application/json" }] }, { "source": "/.well-known/apple-app-site-association", "headers": [{ "key": "Content-Type", "value": "application/json" }] } ] } Firebase Hosting: Use the headers section in firebase.json. JSON
{ "hosting": { "headers": [ { "source": "/apple-app-site-association", "headers": [{ "key": "Content-Type", "value": "application/json" }] }, { "source": "/.well-known/apple-app-site-association", "headers": [{ "key": "Content-Type", "value": "application/json" }] } ] } } GitHub Pages: Serving extensionless files with specific content types can be tricky. Placing the file in the .well-known directory might automatically get the correct content type from GitHub Pages if the content is valid JSON, but it's less guaranteed than explicit configuration. Check their documentation or consider using a build process with GitHub Actions if needed. Cloud Storage (AWS S3, Google Cloud Storage): When uploading the apple-app-site-association file to your bucket, you must explicitly set the Content-Type metadata for the object to application/json. If serving directly from the storage bucket (or via CloudFront/Cloud CDN), ensure this metadata is set correctly.