Skip to main content

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 TypeDescription
text/htmlHTML document
text/cssCSS stylesheet
text/javascriptJavaScript file
image/pngPNG image
application/jsonJSON data
font/woff2WOFF2 web font
video/mp4MP4 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.

note

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>
tip

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>
ExtensionMedia TypeDescription
.wofffont/woffWeb Open Font Format (original)
.woff2font/woff2Web Open Font Format 2 (smaller, faster)
.ttffont/ttfTrueType Font
.otffont/otfOpenType Font
.ttcfont/collectionTrueType Collection (multiple fonts in one file)
.eotapplication/vnd.ms-fontobjectEmbedded OpenType (legacy IE support)
caution

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 .map extension is included for source map files, and .topojson for TopoJSON geographic data.
  • application/ld+json: Used for JSON-LD structured data, commonly embedded in HTML for SEO (Schema.org markup).
  • application/atom+xml and application/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>
note

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:

Comprehensive media type configuration
<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:

.htaccess inside /data/ directory
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>
warning

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

FeatureAddTypeForceType
ScopeMaps specific extensions to typesOverrides type for all files in scope
GranularityPer-extensionPer-directory or per-file-match
PrecedenceCan be overridden by ForceTypeOverrides everything
Use caseDefining types for known file formatsForcing 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:

.htaccess inside /downloads/ directory
<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.

tip

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.