The Ultimate Guide to Configuring Nginx for Media Optimizer
Welcome to the definitive guide for setting up your Nginx server to work seamlessly with Media Optimizer. While our plugin is designed for maximum compatibility, the high-performance nature of Nginx means it doesn’t use .htaccess files. This requires a small, one-time addition to your server’s configuration to enable our lightning-fast image delivery.
This guide will walk you through everything you need to know, from understanding why this is necessary to providing ready-to-copy code blocks for your server administrator.
Table of Contents
Why Does Nginx Need a Special Configuration?
Unlike Apache, which reads .htaccess files in every directory, Nginx reads its entire configuration once upon starting. This is a key reason for its incredible speed, but it means that plugins cannot automatically modify server behavior.
Media Optimizer’s fastest delivery method, “Server Rules,” relies on the server itself to intelligently intercept a request for a standard image (like image.jpg) and serve a next-gen version (image.webp or image.avif) if the browser supports it and the file exists.
To achieve this on Nginx, we need to add a specific location block to your site’s configuration file. This block tells Nginx how to perform this intelligent interception.
Step 1: The Built-in Diagnostic Tool (Your First Port of Call)
Before you touch any configuration files, let our plugin do the hard work. Media Optimizer has a built-in diagnostic system designed specifically for Nginx users.
- Navigate to Settings > Media Optimizer in your WordPress dashboard.
- If the plugin detects you are running on an Nginx server, it will automatically run a background test to check if the rewrite rules are working.
- If everything is already configured correctly, you will see no warnings. You are all set!
- If the test fails, a prominent notice will appear at the top of the settings page. This notice contains the exact, ready-to-use Nginx rules generated specifically for your website’s file structure.
This diagnostic notice is your best friend. In 99% of cases, simply copying the code from this notice and providing it to your hosting support team is all you need to do.
Step 2: Locating Your Nginx Configuration File
If you manage your own server, you’ll need to find your site’s specific configuration file. Nginx configurations can be in several places, but here are the most common locations on a standard Ubuntu/Debian server:
- /etc/nginx/sites-available/your-domain.com.conf (This is the most common place)
- /etc/nginx/sites-enabled/your-domain.com.conf (This is usually a symlink to the file in sites-available)
- /etc/nginx/conf.d/your-domain.com.conf
- /etc/nginx/nginx.conf (Less common for site-specific rules, but possible)
You will need sudo or root access to edit these files.
Step 3: Adding the Media Optimizer Rules
Once you’ve located and opened your site’s configuration file, you need to find the main server { … } block that handles your domain. Inside this block, you will add the rules generated by the plugin.
The rules generated by Media Optimizer look like this (your specific paths may vary slightly):
# BEGIN Media Optimizer Rules
location ~* ^/wp-content/uploads/(?.+)\.(?jpe?g|png|gif)$ {
add_header Vary Accept;
if ($http_accept ~* "image/avif") {
set $ext_avif ".avif";
}
if ($http_accept ~* "image/webp") {
set $ext_webp ".webp";
}
try_files /wp-content/media-optimizer-files/uploads/$path.$ext$ext_avif
/wp-content/media-optimizer-files/uploads/$path.$ext$ext_webp $uri =404;
}
# END Media Optimizer Rules
Where to place this code?
This location block should be placed inside your main server { … } block, typically before the generic location / { … } block that handles standard WordPress requests.
Example server block structure:
server {
listen 80;
server_name dropavif.com www.dropavif.com;
root /var/www/dropavif.com;
index index.php index.html index.htm;
# ... other specific location blocks for static assets might be here ...
# --- PASTE THE MEDIA OPTIMIZER RULES HERE ---
# BEGIN Media Optimizer Rules
location ~* ^/wp-content/uploads/(?.+)\.(?jpe?g|png|gif)$ {
add_header Vary Accept;
if ($http_accept ~* "image/avif") {
set $ext_avif ".avif";
}
if ($http_accept ~* "image/webp") {
set $ext_webp ".webp";
}
try_files /wp-content/media-optimizer-files/uploads/$path.$ext$ext_avif /wp-content/media-optimizer-files/uploads/$path.$ext$ext_webp $uri =404;
}
# END Media Optimizer Rules
# --- END OF MEDIA OPTIMIZER RULES ---
# This is your main WordPress location block
location / {
try_files $uri $uri/ /index.php?$args;
}
# This is your PHP-FPM location block
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php8.3-fpm.sock;
}
# ... other rules ...
}
Breaking Down the Nginx Rules: What Are We Telling the Server?
Understanding the code helps in troubleshooting. Let’s break it down line by line.
location ~* ^/wp-content/uploads/(?.+)\.(?jpe?g|png|gif)$ { ... }
- This line tells Nginx: “Apply the following rules only to requests that are for a JPG, PNG, or GIF file located anywhere inside the /wp-content/uploads/ directory.”
- The ~* makes the match case-insensitive.
- The (?<path>…) and (?<ext>…) parts are named capture groups. They capture the file’s path (e.g., 2025/09/my-image) and its original extension (e.g., jpg) into variables named $path and $ext.
add_header Vary Accept;
- This is a crucial header for caching. It tells browsers and CDNs (like Cloudflare) that the response for this URL can vary depending on the Accept header sent by the client. This prevents a browser that doesn’t support WebP from receiving and caching a WebP file meant for a browser that does.
if ($http_accept ~* "image/avif") { set $ext_avif ".avif"; }
- This checks the visitor’s browser Accept header. If the browser announces it can display image/avif, we set a variable $ext_avif to the value .avif. Otherwise, the variable remains empty.
if ($http_accept ~* "image/webp") { set $ext_webp ".webp"; }
This does the same thing for the WebP format.
try_files /wp-content/media-optimizer-files/uploads/$path.$ext$ext_avif ... $uri =404;
- This is the core of the magic. try_files tells Nginx to check for the existence of files in a specific order and serve the first one it finds.
- First, it checks for AVIF: It constructs a path like /wp-content/media-optimizer-files/uploads/2025/09/my-image.jpg.avif. If the browser supported AVIF, $ext_avif is .avif, and Nginx looks for that file.
- Then, it checks for WebP: If the AVIF file wasn’t found (or the browser didn’t support it), it constructs a path like /wp-content/media-optimizer-files/uploads/2025/09/my-image.jpg.webp. If the browser supported WebP, $ext_webp is .webp, and Nginx looks for that file.
- Then, it falls back to the original: $uri is the original requested URI (e.g., /wp-content/uploads/2025/09/my-image.jpg). If neither AVIF nor WebP was found or supported, Nginx serves the original file.
- Finally, =404: If for some reason even the original file doesn’t exist, it returns a 404 Not Found error.
Step 4: Test and Reload the Nginx Configuration
After saving your changes, it’s critical to test the configuration before reloading the server. A syntax error could take your entire site offline.
- Test the configuration:
sudo nginx -t
If everything is correct, you will see a message like:
nginx: the configuration file /etc/nginx/nginx.conf
syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
- Reload Nginx:
If the test is successful, gracefully reload the Nginx service to apply the changes without dropping any connections.
sudo systemctl reload nginx
After reloading, go back to the Media Optimizer settings page. The error notice should now be gone, and your images should start being served in next-gen formats