Documentation

Document Policy

Configure Document Policy reporting to enforce performance standards and detect when resources violate your policies for image sizes, script execution, and media dimensions.

New to Document Policy monitoring? Read our Document Policy overview to understand the benefits before diving into configuration.

What is Document Policy?

Document Policy is a WICG specification that provides a framework for enforcing performance constraints on web documents. Using HTTP headers, you define policies that control behaviors like image sizing, script execution, and resource loading — and browsers enforce these rules automatically.

Unlike Permissions Policy which controls access to powerful APIs (camera, microphone, geolocation), Document Policy focuses on performance behaviors. It uses parametrized values (decimals, thresholds) rather than simple boolean enable/disable. For example, you can set oversized-images=2.0 to allow images up to 2× their container size, while blocking anything larger.

Document Policy controls 10 performance behaviors: block document.write() and synchronous XHR, enforce image compression ratios, require dimensions on media elements, restrict animations to GPU-friendly properties, and more. When a resource violates your policy, the browser can block it and send a violation report.

Specification

Browser Support

Document Policy has ~77% global browser support, covering Chromium-based browsers. Firefox and Safari do not support Document Policy.

Browser Support Notes
Chrome 85+ Full support including reporting
Edge 85+ Full support including reporting
Opera 71+ Full support
Firefox Not supported
Safari Not supported
Browser limitation: Firefox and Safari do not support Document Policy. Violation reports will only come from Chromium-based browsers (~77% of users). Plan your policy testing accordingly.

Why Monitor Document Policy Violations?

Document Policy violations reveal important information about performance issues:

  • Performance visibility — See every oversized image, blocking script, and resource violation. Know exactly what’s slowing down your pages.
  • Proactive optimization — Catch performance regressions in staging before they reach production. Identify issues during CI/CD rather than through user complaints.
  • Third-party accountability — Track which vendor scripts violate your performance standards. See which integrations use document.write() or synchronous XHR.
  • Regression detection — Get alerted when new deployments introduce oversized assets or blocking behaviors that degrade Core Web Vitals.
  • Compliance evidence — Document that performance policies are enforced. Prove to stakeholders that your performance budget is being maintained.

Who Benefits

  • Performance engineers — Enforce performance budgets and identify optimization opportunities across the site
  • DevOps teams — Integrate performance policy violations into CI/CD pipelines and deployment gates
  • Frontend architects — Set performance standards that apply to all teams and third-party integrations
  • Engineering leadership — Track performance governance metrics and demonstrate compliance with performance SLAs

When to Enable

Document Policy monitoring is recommended for:

  • E-commerce sites — Where page speed directly impacts conversion rates and revenue
  • High-traffic applications — Where performance regressions affect large numbers of users
  • Mobile-first sites — Where bandwidth constraints make image optimization critical
  • Sites with third-party scripts — Where vendor behavior needs to be monitored and governed

Start with Report-Only mode to understand your current violations before enforcing restrictions.

How to Configure

Step 1: Set Up the Reporting Endpoint

First, define where browsers should send violation reports using the Reporting-Endpoints header:

HTTP Define the reporting endpoint
Reporting-Endpoints: default="https://reporting-api.app/browser-reports/YOUR-ENDPOINT-UUID"

Replace YOUR-ENDPOINT-UUID with your application's unique endpoint from the reporting-api.app dashboard.

Step 2: Enable Report-Only Mode for Testing

Before enforcing your policy, test it using Document-Policy-Report-Only. This sends violation reports without blocking any resources, letting you see what would fail:

HTTP Report-Only mode for safe testing
Document-Policy-Report-Only: oversized-images=2.0, sync-script=?0, document-write=?0, *;report-to="default"
Reporting-Endpoints: default="https://reporting-api.app/browser-reports/YOUR-UUID"

This configuration would report (but not block) any image exceeding 2× its container size, any parser-blocking script, or any use of document.write().

Start with Report-Only: Always start with Document-Policy-Report-Only before enforcing policies. Your site may have legitimate cases where policies are violated. Report-Only mode reveals these without breaking functionality.

Step 3: Configure Policy Directives

Define which behaviors to control. Document Policy supports two types of directives:

Boolean Directives

Set to ?0 to disable a behavior:

HTTP Boolean directive example
Document-Policy-Report-Only: sync-script=?0, sync-xhr=?0, document-write=?0, *;report-to="default"

This blocks parser-blocking scripts, synchronous XHR, and document.write().

Decimal Directives

Set a threshold value:

HTTP Decimal directive example
Document-Policy-Report-Only: oversized-images=2.0, lossy-images-max-bpp=0.5, *;report-to="default"

This policy:

  • oversized-images=2.0 — Allow images up to 2× their container size
  • lossy-images-max-bpp=0.5 — Require lossy images to be under 0.5 bytes per pixel

Step 4: Monitor Reports and Identify Violations

After deploying Report-Only mode, monitor incoming reports in your dashboard. Look for:

  • Image violations — Oversized or poorly compressed images that need optimization
  • Script violations — Parser-blocking scripts that should use async or defer
  • Third-party violations — Vendor scripts using deprecated patterns like document.write()

For each violation, decide whether to:

  • Fix the resource — Optimize the image, update the script
  • Adjust the threshold — Loosen the policy if the limit is too strict
  • Accept and block — The behavior is unacceptable; proceed with enforcement

Step 5: Switch to Enforcement

Once you've resolved all issues, switch from Report-Only to enforced mode:

HTTP Enforced Document Policy with reporting
Document-Policy: oversized-images=2.0, sync-script=?0, document-write=?0, *;report-to="default"
Reporting-Endpoints: default="https://reporting-api.app/browser-reports/YOUR-UUID"

Remove the -Report-Only suffix to start blocking violating resources. Keep *;report-to="default" to continue receiving reports about blocked resources.

Keep reporting enabled: Continue monitoring even after enforcement. New deployments, third-party updates, or CMS content may introduce new violations. Ongoing reports help you maintain performance standards.

Step 6: Set Up Integrations

Route Document Policy violation reports to your existing tools:

See the Integrations documentation for setup instructions.

Understanding Violation Reports

When a resource violates your Document Policy, browsers send JSON reports to your endpoint. These reports identify exactly which policy was violated and where.

Report Fields

Field Description
policyId The policy directive that was violated (e.g., oversized-images, sync-script)
disposition enforce if blocked, report if Report-Only mode
message Human-readable description of the violation
sourceFile URL of the resource that violated the policy
lineNumber Line number where the violation occurred (for scripts)
columnNumber Column number where the violation occurred

Example Report

JSON Document Policy violation (oversized image)
{
  "type": "document-policy-violation",
  "age": 23,
  "url": "https://example.com/products/widget",
  "body": {
    "policyId": "oversized-images",
    "disposition": "enforce",
    "message": "Image is 4x larger than its container",
    "sourceFile": "https://cdn.example.com/images/hero-banner.jpg"
  }
}

This report shows a hero banner image that's 4× larger than its container, violating the oversized-images policy. The disposition: "enforce" indicates the image was blocked (replaced with a placeholder).

Interpreting Disposition

  • report — Report-Only mode. The resource was allowed but logged. Use this for testing.
  • enforce — Enforcement mode. The resource was blocked. Users see a placeholder or broken resource.

Common Policy Directives

Document Policy supports 10 directives grouped into two categories: boolean (enable/disable) and decimal (threshold-based).

Boolean Directives

Set to ?0 to disable these behaviors:

Directive Controls Performance Impact
sync-script Parser-blocking scripts High — blocks render until script loads/executes
sync-xhr Synchronous XMLHttpRequest High — blocks main thread during request
document-write document.write() API High — blocks parser, can break page on slow connections
unsized-media Media without explicit dimensions Medium — causes layout shift (CLS)
layout-animations Non-GPU animations Medium — forces layout recalculation
font-display-late-swap Late font swapping Medium — causes layout shift when fonts load

Image Optimization Directives

Set decimal thresholds to enforce image quality standards:

Directive Controls Recommended
oversized-images Max downscaling ratio (intrinsic vs rendered size) 2.0 or lower
lossy-images-max-bpp Bytes per pixel for lossy images (1KB overhead) 0.5 (0.2 for WebP)
lossless-images-max-bpp Bytes per pixel for lossless images (10KB overhead) 1.0 (0.5 for WebP)
lossless-images-strict-max-bpp Strict lossless check (1KB overhead) 0.5

Based on web.dev guidance and Web Performance Calendar recommendations:

HTTP Recommended Document Policy configuration
Document-Policy-Report-Only: oversized-images=2.0, lossy-images-max-bpp=0.5, lossless-images-max-bpp=1.0, sync-script=?0, sync-xhr=?0, document-write=?0, unsized-media=?0, *;report-to="default"
Start conservative: Begin with looser thresholds (oversized-images=3.0) and tighten them as you optimize your assets. This prevents blocking legitimate content while you improve.

Directive Syntax

Document Policy uses Structured Headers syntax. Here's how to format your policies:

Syntax Meaning Example
directive=?0 Boolean false (disable) sync-script=?0
directive=?1 Boolean true (enable, default) sync-script=?1
directive=N.N Decimal threshold oversized-images=2.0
*;report-to="name" Report all violations to endpoint *;report-to="default"

Multiple directives are combined with commas:

HTTP Multiple directives
Document-Policy: oversized-images=2.0, sync-script=?0, document-write=?0, *;report-to="default"
Report-to placement: The *;report-to="default" parameter must come at the end of your policy and applies to all directives. The * is a wildcard meaning “for all policies.”

Server Configuration Examples

Nginx

Nginx nginx.conf
server {
    # ... your existing configuration ...

    # Reporting endpoint
    add_header Reporting-Endpoints 'default="https://reporting-api.app/browser-reports/YOUR-UUID"' always;

    # Document Policy with reporting (Report-Only for testing)
    add_header Document-Policy-Report-Only 'oversized-images=2.0, sync-script=?0, document-write=?0, *;report-to="default"' always;

    # Or enforced mode:
    # add_header Document-Policy 'oversized-images=2.0, sync-script=?0, document-write=?0, *;report-to="default"' always;
}

Ruby on Rails

Ruby config/application.rb or initializer
# Add Document Policy headers with reporting
# Note: Use lowercase header names for Rack 3 compatibility
config.action_dispatch.default_headers.merge!(
  "reporting-endpoints" => 'default="https://reporting-api.app/browser-reports/YOUR-UUID"',
  # Report-Only for testing:
  "document-policy-report-only" => 'oversized-images=2.0, sync-script=?0, document-write=?0, *;report-to="default"'
  # Or enforced mode:
  # "document-policy" => 'oversized-images=2.0, sync-script=?0, document-write=?0, *;report-to="default"'
)

Apache

Apache .htaccess or httpd.conf
Header always set Reporting-Endpoints 'default="https://reporting-api.app/browser-reports/YOUR-UUID"'

# Report-Only for testing:
Header always set Document-Policy-Report-Only 'oversized-images=2.0, sync-script=?0, document-write=?0, *;report-to="default"'

# Or enforced mode:
# Header always set Document-Policy 'oversized-images=2.0, sync-script=?0, document-write=?0, *;report-to="default"'

Troubleshooting

Reports Not Appearing

  • Check browser support — Document Policy reporting only works in Chromium-based browsers (Chrome 85+, Edge 85+). Firefox and Safari do not support this feature.
  • Verify headers are sent — Use browser DevTools (Network tab) to confirm both Document-Policy (or Document-Policy-Report-Only) and Reporting-Endpoints headers are present.
  • Check report-to parameter — The policy must include *;report-to="default" to send reports.
  • Trigger a violation — Ensure a resource is actually violating your policy. Try loading an obviously oversized image to test.

Resources Still Loading Despite Policy

  • Check Report-Only vs EnforceDocument-Policy-Report-Only sends reports but doesn't block. Switch to Document-Policy to enforce.
  • Verify threshold values — Ensure your thresholds are actually being exceeded. An oversized-images=4.0 policy won't block a 3× oversized image.
  • Check header parsing — Malformed headers may be silently ignored. Use browser DevTools to check for parsing errors.

Policy Syntax Errors

  • Use correct boolean syntax — Boolean values use ?0 and ?1, not true/ false
  • Decimal values need a decimal point — Use 2.0, not 2
  • Wildcard report-to at end*;report-to="default" must come after all other directives

Next Steps