Content negotiation is the practice of serving different versions of your content based on the user’s device, language preferences, or request context. WordPress handles some content negotiation automatically — responsive themes serve different layouts based on viewport size — but advanced negotiation requires custom implementation. Proper content negotiation improves user experience across different contexts.
This guide covers how to implement content negotiation in WordPress.
Language Negotiation
WordPress doesn’t negotiate languages automatically. Use the Accept-Language HTTP header to detect the user’s preferred language and redirect to the appropriate language version. Multilingual plugins like Polylang and WPML handle language negotiation automatically. For custom implementations, check the Accept-Language header with $_SERVER[‘HTTP_ACCEPT_LANGUAGE’] and match it against your available languages.
Store the user’s language preference in a cookie or session after the first visit. This prevents redirecting them on every request.
Device Negotiation
Serve different content or templates based on the user’s device. Use WordPress’s wp_is_mobile() function to check if the request comes from a mobile device. Load different templates, scripts, or content blocks based on the device type. For more precise detection, analyze the User-Agent header with a library like Mobile Detect.
Modern responsive design eliminates the need for most device-specific content negotiation, but some use cases still benefit — serving smaller images to mobile devices or offering simplified navigation on small screens.
Authentication Negotiation
Serve different content based on authentication state. Logged-in users see different content than anonymous visitors. WordPress handles this through is_user_logged_in() checks in templates. For the REST API, use the X-WP-Nonce header to authenticate requests. Serve cached content for anonymous users and dynamic content for authenticated users.
For membership sites, use capability checks to determine what content a user can access.
Format Negotiation
Serve content in different formats based on the request. The WordPress REST API handles format negotiation through the Accept header — requests for application/json return JSON, while web requests return HTML. For custom endpoints, support multiple output formats with the format parameter. Return HTML, JSON, XML, or CSV based on the request.
Use the WP_Accept_Headers class to parse Accept headers and determine the best response format.
Cache-Aware Negotiation
Content negotiation complicates caching because different users get different content. Use vary headers to tell caching layers that the response varies based on specific request properties. Add Vary: Accept-Language, Vary: User-Agent, and Vary: Cookie headers to your responses so caches store separate versions for each variation.
For high-traffic sites, minimize the number of variations to keep cache efficiency high.
Il punto fondamentale
Content negotiation lets you serve the right content to each user. Negotiate language based on browser preferences, device type for optimized experiences, authentication state for personalized content, and output format for API consumers. Configure vary headers to maintain cache efficiency while serving different content to different users.




