Concurrent visitors over the last 30 minutes. (~)
Peak concurrent visitors -
Yesterday: 0 / Today:
0
1<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests" />
upgrade-insecure-requests is a CSP (Content-Security-Policy) directive that tells the browser to automatically upgrade every HTTP request in a web page (images, scripts, APIs, and so on) to HTTPS.
Loading HTTP resources on a web page served over HTTPS can open security holes such as XSS, MITM, and data interception, so most browsers block these resources or show a mixed content warning.
Automatically converting HTTP resource requests to HTTPS is an easy way to solve this mixed content problem.
In a development environment, you usually use an HTTP address such as http://localhost:5173.
With the upgrade-insecure-requests directive, even a local development server like this would have to be redirected to HTTPS, but common browsers such as Chrome and Firefox make an exception so that HTTP requests still work.
Safari, however, is a well-known browser that makes no such exception and strictly tries to redirect HTTP requests to HTTPS.
So when http://localhost is redirected to https://localhost, you can no longer reach a local development server that does not support HTTPS.
A simple way to fix this is to remove the Upgrade Insecure Requests directive from your local development environment.
Apply the directive conditionally, for example with environment variables, so that it is only used in production.
Vite configuration example
Inject the CSP meta tag conditionally at build time.
1npm i -D vite-plugin-html
1234567891011121314151617181920import { defineConfig } from 'vite' import { createHtmlPlugin } from 'vite-plugin-html' const tags = [] if (process.env.NODE_ENV === 'development') { tags.push({ tag: 'meta', attrs: { httpEquiv: 'Content-Security-Policy', content: 'upgrade-insecure-requests' } }) } export default defineConfig({ plugins: [ createHtmlPlugin({ inject: { tags } }) ] })
Next.js configuration example
Add the CSP header to requests for every path.
123456789101112131415161718import type { NextConfig } from 'next' const nextConfig: NextConfig = { async headers() { return [ { source: '/:path*', headers: [ { key: 'Content-Security-Policy', value: process.env.NODE_ENV === 'production' ? 'upgrade-insecure-requests' : '' } ] } ] } } export default nextConfig
SvelteKit configuration example
Add the CSP meta tag conditionally in the application.
1234567891011<script lang="ts"> import { dev } from '$app/environment' </script> <svelte:head> {#if !dev} <meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests" /> {/if} </svelte:head>
HTTPS development server example
The first time you run the local Vite development server, you may be asked to enter your password, and a local certificate is installed on your system and browsers.
After that, you can access the server at https://localhost.
1npm i -D vite-plugin-mkcert
12345678import { defineConfig } from 'vite' import mkcert from 'vite-plugin-mkcert' export default defineConfig({ plugins: [ mkcert() ] })