Media Types in .htaccess
Every file your web server delivers comes with a media type (also known as a MIME type) that tells the browser what kind of content it is receiving. When Apache sends a CSS file, it labels it as text/css. When it sends a JPEG image, it labels it as image/jpeg. This labeling determines how the browser handles the file: whether it renders it, executes it, plays it, or offers it as a download.
This guide explains what media types are, why they matter, how to use the AddType and ForceType directives to configure them, and how to handle modern file formats that Apache may not recognize out of the box.
What Are Media Types
A media type (formally called a MIME type, from Multipurpose Internet Mail Extensions) is a standardized label that identifies the format of a file. It consists of two parts separated by a slash:
type/subtype
For example:
| Media Type | Description |
|---|---|
text/html | HTML document |
text/css | CSS stylesheet |
text/javascript | JavaScript file |
image/png | PNG image |
application/json | JSON data |
font/woff2 | WOFF2 web font |
video/mp4 | MP4 video |
When Apache serves a file, it looks at the file extension, maps it to a media type using its internal configuration (provided by the mod_mime module), and includes that media type in the Content-Type HTTP response header:
Content-Type: text/css
The browser reads this header and decides what to do with the content. A text/css response gets applied as a stylesheet. A text/javascript response gets executed as code. An application/octet-stream response triggers a file download.
Why Correct Media Types Matter
Serving files with incorrect or missing media types causes real problems that affect functionality, security, and performance.
Browser Behavior
Browsers rely on the Content-Type header to determine how to process a response. If a CSS file is served as text/plain, the browser will not apply it as a stylesheet. If a JavaScript file has the wrong type, modern browsers may refuse to execute it entirely.
# What the browser sees when a CSS file is served with wrong type:
Content-Type: text/plain
# Result: The stylesheet is ignored. The page appears unstyled.
Security (MIME Sniffing)
When a file is served without a media type or with a generic one like application/octet-stream, some browsers attempt to guess the content type by examining the file's contents. This is called MIME sniffing, and it can be exploited by attackers. For example, a file that looks like HTML could be "sniffed" as HTML and executed in the browser, even if it was uploaded as a text file.
Setting correct media types, combined with the X-Content-Type-Options: nosniff header, prevents this class of attack.
Performance and Caching
Correct media types are a prerequisite for proper caching and compression. Many server configurations apply gzip or Brotli compression only to specific media types (text/css, text/javascript, application/json, etc.). If your files have incorrect types, they may be served uncompressed, increasing load times.
SEO and Accessibility
Search engine crawlers also use media types to understand your content. Serving an XML sitemap as text/plain instead of application/xml may cause crawlers to ignore it. Serving a web manifest with the wrong type can prevent browsers from recognizing your site as a Progressive Web App.
Changing the media type of a file does not update its Last-Modified header. If a file was previously cached by a browser or CDN with the wrong type, the cached version may continue to be served. You may need to "touch" the affected files (update their modification date) or bust the cache to ensure visitors receive the corrected Content-Type header.
The AddType Directive
The AddType directive is provided by Apache's mod_mime module and lets you associate a media type with one or more file extensions.
The syntax is:
AddType media-type extension [extension] ...
- media-type: The MIME type to assign (e.g.,
text/javascript). - extension: One or more file extensions, without the leading dot.
A simple example:
# Associate .json files with the JSON media type
AddType application/json json
You can map multiple extensions to the same type on a single line:
# Both .json and .map files are served as application/json
AddType application/json json map
Where to Place AddType
AddType directives should be wrapped in an <IfModule> block to prevent errors if mod_mime is not loaded:
<IfModule mod_mime.c>
AddType application/json json
AddType text/javascript js mjs
</IfModule>
While Apache recognizes many common file types out of the box (HTML, CSS, standard images), modern formats like AVIF, WOFF2, WebAssembly, and Web App Manifests are often not configured by default, especially on older server installations. Explicitly defining these types in your .htaccess ensures consistent behavior regardless of the server's base configuration.
Mapping Extensions to Media Types
Below is a comprehensive reference of AddType mappings organized by category. You do not need to include all of these in every project. Pick the ones that match the file types your site actually serves.
Web Fonts
Web fonts are among the most commonly misconfigured file types. Older Apache installations may not recognize modern font formats at all, causing browsers to reject them.
<IfModule mod_mime.c>
AddType font/woff woff
AddType font/woff2 woff2
AddType font/ttf ttf
AddType font/otf otf
AddType font/collection ttc
AddType application/vnd.ms-fontobject eot
</IfModule>
| Extension | Media Type | Description |
|---|---|---|
.woff | font/woff | Web Open Font Format (original) |
.woff2 | font/woff2 | Web Open Font Format 2 (smaller, faster) |
.ttf | font/ttf | TrueType Font |
.otf | font/otf | OpenType Font |
.ttc | font/collection | TrueType Collection (multiple fonts in one file) |
.eot | application/vnd.ms-fontobject | Embedded OpenType (legacy IE support) |
You may encounter older configurations using application/font-woff or application/x-font-ttf for font types. These are outdated and non-standard. The font/* types listed above are the current IANA-registered media types and should be used instead.
SVG
SVG files are XML-based vector images. They need to be served with the correct type for browsers to render them as images rather than downloading them or displaying raw XML.
<IfModule mod_mime.c>
AddType image/svg+xml svg svgz
</IfModule>
The .svgz extension is for gzip-compressed SVG files. When serving .svgz files, you also need to set the correct encoding header:
<IfModule mod_mime.c>
AddType image/svg+xml svg svgz
AddEncoding gzip svgz
</IfModule>
Without AddEncoding gzip svgz, the browser receives a gzipped file but does not know it needs to decompress it, resulting in a broken image or a garbled download.
JSON and XML
Data interchange formats are essential for APIs, configuration files, and structured data.
<IfModule mod_mime.c>
# JSON formats
AddType application/json json map topojson
AddType application/ld+json jsonld
AddType application/geo+json geojson
# XML formats
AddType application/xml xml
AddType application/atom+xml atom
AddType application/rss+xml rss
AddType application/rdf+xml rdf
</IfModule>
A few notes on these types:
application/json: The standard JSON type. The.mapextension is included for source map files, and.topojsonfor TopoJSON geographic data.application/ld+json: Used for JSON-LD structured data, commonly embedded in HTML for SEO (Schema.org markup).application/atom+xmlandapplication/rss+xml: Feed formats. Correct typing ensures feed readers can auto-discover and parse your feeds.
Video and Audio
Modern websites increasingly serve media directly. Ensure these formats are properly recognized:
<IfModule mod_mime.c>
# Audio
AddType audio/mp4 f4a f4b m4a
AddType audio/ogg oga ogg opus
# Video
AddType video/mp4 f4v f4p m4v mp4
AddType video/ogg ogv
AddType video/webm webm
</IfModule>
If the browser does not recognize the media type of a video or audio file, the HTML5 <video> and <audio> elements will fail to play the content, often without showing any error message.
Modern Image Formats
Newer image formats like AVIF, HEIF, and WebP offer significantly better compression than JPEG and PNG, but many Apache installations do not include them by default.
<IfModule mod_mime.c>
# Modern image formats
AddType image/webp webp
AddType image/avif avif
AddType image/avis avis
AddType image/heic heic
AddType image/heif heif
AddType image/heics heics
AddType image/heifs heifs
# Legacy but still common
AddType image/bmp bmp
AddType image/x-icon cur ico
</IfModule>
WebManifest and Other Modern Types
Progressive Web Apps, WebAssembly, and other modern web technologies introduce file types that Apache likely does not know about:
<IfModule mod_mime.c>
# Web App Manifests
AddType application/manifest+json webmanifest
AddType application/x-web-app-manifest+json webapp
# WebAssembly
AddType application/wasm wasm
# JavaScript (including ES modules)
AddType text/javascript js mjs
# Other useful types
AddType text/calendar ics
AddType text/markdown markdown md
AddType text/vcard vcard vcf
AddType text/vtt vtt
AddType text/cache-manifest appcache
</IfModule>
The correct media type for JavaScript is text/javascript. You may encounter application/javascript or application/x-javascript in older configurations. While these still work in most browsers, the IANA standard and all modern specifications use text/javascript. The .mjs extension is for ES module files, which use the same media type.
Complete AddType Configuration
Here is a full, copy-ready configuration that covers all the types discussed above:
<IfModule mod_mime.c>
# Data interchange
AddType application/atom+xml atom
AddType application/json json map topojson
AddType application/ld+json jsonld
AddType application/rss+xml rss
AddType application/geo+json geojson
AddType application/rdf+xml rdf
AddType application/xml xml
# JavaScript
AddType text/javascript js mjs
# Manifest files
AddType application/manifest+json webmanifest
AddType application/x-web-app-manifest+json webapp
AddType text/cache-manifest appcache
# Audio
AddType audio/mp4 f4a f4b m4a
AddType audio/ogg oga ogg opus
# Video
AddType video/mp4 f4v f4p m4v mp4
AddType video/ogg ogv
AddType video/webm webm
# Images
AddType image/bmp bmp
AddType image/svg+xml svg svgz
AddType image/webp webp
AddType image/x-icon cur ico
AddType image/avif avif
AddType image/avis avis
AddType image/heic heic
AddType image/heif heif
AddType image/heics heics
AddType image/heifs heifs
# WebAssembly
AddType application/wasm wasm
# Web fonts
AddType font/woff woff
AddType font/woff2 woff2
AddType font/ttf ttf
AddType font/otf otf
AddType font/collection ttc
AddType application/vnd.ms-fontobject eot
# Other
AddType text/calendar ics
AddType text/markdown markdown md
AddType text/vcard vcard vcf
AddType text/vtt vtt
AddType text/x-component htc
</IfModule>
The ForceType Directive
While AddType maps file extensions to media types, ForceType overrides the media type for all files within a specific context, regardless of their extension. This is useful when you need every file in a directory or matching a pattern to be treated as a specific type.
The syntax is:
ForceType media-type
Forcing a Type for an Entire Directory
If you have a directory full of files that should all be treated as plain text, regardless of their extensions:
ForceType text/plain
Every file in the /data/ directory, whether it is a .html, .php, or .exe file, will be served as text/plain. The browser will display its raw contents instead of rendering or executing it.
Forcing a Type for Specific Files
You can use <Files> or <FilesMatch> directives to target specific files:
# Force all .api files to be treated as JSON
<FilesMatch "\.api$">
ForceType application/json
</FilesMatch>
# Force a specific file to be treated as HTML
<Files "readme">
ForceType text/html
</Files>
Practical Use Case: Serving Extensionless Files
Some applications generate files without extensions (common in REST APIs or static site generators). You can force these to be served with the correct type:
# Serve extensionless files in the /api/ directory as JSON
<Directory "/var/www/html/api">
ForceType application/json
</Directory>
ForceType overrides everything, including AddType and Apache's built-in type detection. Use it sparingly and only when you are certain that all files in the target scope should have the same type. Applying ForceType text/plain at the wrong level could break CSS, JavaScript, and images across your entire site.
ForceType vs AddType
| Feature | AddType | ForceType |
|---|---|---|
| Scope | Maps specific extensions to types | Overrides type for all files in scope |
| Granularity | Per-extension | Per-directory or per-file-match |
| Precedence | Can be overridden by ForceType | Overrides everything |
| Use case | Defining types for known file formats | Forcing a specific type for a group of files |
Removing or Overriding Types
Sometimes you need to undo or change a media type that is already configured, either by Apache's defaults or by a higher-level configuration.
RemoveType Directive
The RemoveType directive removes any media type association for a given extension:
<IfModule mod_mime.c>
# Remove the default type for .html files
RemoveType .html
</IfModule>
After this directive, .html files will be served with Apache's default type (usually text/plain or whatever DefaultType is set to).
Practical example: Suppose you want .html files in a specific directory to be downloaded rather than displayed:
<IfModule mod_mime.c>
RemoveType .html
AddType application/octet-stream html
</IfModule>
First, RemoveType clears the existing text/html association. Then, AddType assigns application/octet-stream, which triggers a download in the browser.
Overriding Types Directly
If you simply want to change a type, you can use AddType without RemoveType. The new AddType directive overrides the previous one for the same extension:
<IfModule mod_mime.c>
# Override the default type for .svg files
# Even if Apache already maps .svg to something else
AddType image/svg+xml svg svgz
</IfModule>
Common Mistake: Wrapping in the Wrong Module Check
Wrong approach:
# mod_expires has nothing to do with media types!
<IfModule mod_expires.c>
AddType application/json json
AddType text/javascript js
</IfModule>
The AddType directive belongs to mod_mime, not mod_expires. While this might work if both modules are loaded, it creates confusion and could silently fail if mod_expires is disabled while mod_mime remains active.
Correct approach:
<IfModule mod_mime.c>
AddType application/json json
AddType text/javascript js
</IfModule>
Always wrap AddType, ForceType, and RemoveType directives in <IfModule mod_mime.c> blocks.
After making changes to your media type configuration, verify the results by checking the response headers. You can use browser developer tools (Network tab, click on a file, look at the Response Headers) or curl:
curl -I https://example.com/script.js
Look for the Content-Type header in the response to confirm it matches your expectations.
Correctly configuring media types is a foundational step in web server setup. It ensures browsers render your content properly, enables compression and caching to work correctly, prevents security vulnerabilities from MIME sniffing, and helps search engines understand your site structure. Take the time to audit your site's file types and add the appropriate AddType directives for any formats Apache does not recognize by default.