Some patterns require more than straightforward location matching. For single-page applications using HTML5 history-mode routing, every request should fall through to the application's bootstrap file: location / { try_files $uri $uri/ /index.html; }. The canonical Vue or React snippet then adds a parallel location for fingerprinted assets with long-lived caching: location ~* \.(?:js|css|woff2?|png|jpg|svg)$ { expires 1y; add_header Cache-Control "public, immutable"; }. WebSockets are another special case: the proxy needs HTTP/1.1 with the Upgrade handshake preserved, which is achieved by proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; and a generous proxy_read_timeout 86400; so idle sockets are not closed at the default 60-second mark.
For more flexible conditionals, the if directive is powerful but famously tricky: the official wiki warns that if is "evil" when used outside a location block or when checking request headers. The safe pattern is to test only on built-in variables such as $http_x_custom, or to lift the logic out of if altogether using map and geo. The map directive builds a new variable by matching an input against patterns and is evaluated once per request: map $http_accept_language $lang { default en; ~^fr fr; }. The geo directive does the same thing keyed on the client IP, ideal for geolocation and coarse-grained allow/deny lists. When upstream hostnames must be resolved dynamically (for example, when targeting Consul- or Kubernetes-style service discovery), declare a resolver directive — resolver 1.1.1.1 8.8.8.8 valid=300s; — because nginx does not inherit the system resolver otherwise.
Two related features handle request-handling logic that should never be exposed to clients. A location marked internal; can be reached only via internal redirects (X-Accel-Redirect headers from upstream, error_page handlers, or rewrite ... last), and direct client requests return 404. The X-Accel-Redirect pattern is the canonical way to delegate access-controlled downloads to nginx: the upstream decides whether the user is authorised and returns X-Accel-Redirect: /protected/file.pdf, which nginx then serves from an internal location that enforces its own checks. For streaming large responses such as video or Server-Sent Events, disable buffering explicitly with proxy_buffering off; proxy_cache off; add_header X-Accel-Buffering no; chunked_transfer_encoding on; so nginx does not hold the whole response in memory before forwarding.
Security headers and minor hardening round out a production configuration. The standard set is X-Frame-Options (clickjacking protection, for example SAMEORIGIN or DENY), X-Content-Type-Options: nosniff (stops MIME sniffing), a Referrer-Policy such as strict-origin-when-cross-origin, a Content-Security-Policy appropriate to your application, and a Permissions-Policy. Always pass the always parameter so the headers are added to error responses too. Hidden files should never be reachable: location ~ /\. { deny all; return 404; } blocks /.git, /.env, and similar paths. To strip identifying headers from upstream responses, use proxy_hide_header X-Powered-By;, and to hide the nginx version itself use server_tokens off;. The headers-more module adds more_clear_headers, but it is not part of open-source nginx — the equivalent in vanilla nginx is proxy_hide_header per header name.