Skip to content

Provision local HTTPS certificates automatically when running Vite with localHttps - #3953

Merged
fredericoo merged 9 commits into
previewfrom
fb-local-https-vite-plugin-mkcert
Aug 21, 2026
Merged

Provision local HTTPS certificates automatically when running Vite with localHttps#3953
fredericoo merged 9 commits into
previewfrom
fb-local-https-vite-plugin-mkcert

Conversation

@fredericoo

@fredericoo fredericoo commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

TL;DR: Local HTTPS for Vite-based setups required a manual, macOS-specific mkcert setup before Customer Account flows worked. This PR (stacked on #3936) makes provisioning portable across macOS, Linux, and Windows while keeping the system trust change explicit and reversible.

Before

brew install mkcert
mkcert -install
mkdir -p ~/.shopify/hydrogen/certs
mkcert -cert-file ~/.shopify/hydrogen/certs/local.tryhydrogen.dev.pem \
  -key-file ~/.shopify/hydrogen/certs/local.tryhydrogen.dev-key.pem local.tryhydrogen.dev

After

vite dev                                # asks before provisioning missing certificates
npx hydrogen certs install              # provision explicitly
npx hydrogen certs uninstall            # remove Hydrogen's certificate files
npx hydrogen certs uninstall --remove-ca # also remove mkcert's shared CA

What this changes

  • localHttps() detects missing certificates during vite dev and explains that Hydrogen will download mkcert, modify the system trust store, and create a certificate before asking for confirmation. Declining or running non-interactively leaves HTTPS disabled and prints the explicit installation command.
  • Downloads a pinned mkcert v1.4.4 binary for macOS, Linux, or Windows on x64/arm64, verifies the platform-specific SHA-256 checksum before execution, and caches it under ~/.shopify/hydrogen/mkcert/.
  • Adds paired hydrogen certs install and hydrogen certs uninstall commands. Uninstall removes Hydrogen's certificate, key, and cached mkcert binary by default. --remove-ca additionally warns and runs mkcert -uninstall because that CA may be shared with unrelated projects.
  • Adds provisionLocalHttps() for frameworks that need certificate paths before the Vite plugin runs, including Nuxt and SolidStart.
  • Keeps build, preview, and CI free of automatic provisioning. Failures degrade to the existing warning with the failure reason, explicit CLI command, and manual mkcert steps.
  • Makes the root https:setup script cross-platform and updates the packaged local HTTPS skill and repository guidance.

Developer impact

Extends the existing minor changeset for @shopify/hydrogen. It adds the provisionLocalHttps() / ProvisionLocalHttpsOptions exports under @shopify/hydrogen/vite and the paired certificate CLI commands. Existing localHttps() call sites need no changes.

Risk

  • Accepting the first-run prompt or running hydrogen certs install installs mkcert's local CA into system trust stores and may prompt for a password.
  • mkcert uses one shared CA by default. certs uninstall therefore leaves it trusted; removing it requires the explicit --remove-ca flag and can make certificates from other projects untrusted.
  • mkcert v1.4.4 is pinned to six platform checksums. Updating mkcert requires updating the version and every checksum.

How to Test

  1. Move any existing Hydrogen certificate state aside: mv ~/.shopify/hydrogen ~/.shopify/hydrogen.bak.
  2. Run pnpm install && pnpm build:pkgs.
  3. Run pnpm --filter @shopify/hydrogen-example-astro https:dev.
  4. Decline the prompt and confirm no certificate is installed and the warning points to npx hydrogen certs install.
  5. Start the command again, accept the prompt, and confirm the app serves on https://local.tryhydrogen.dev:5173 with a trusted certificate.
  6. Run node packages/hydrogen/bin/hydrogen.mjs certs uninstall and confirm the Hydrogen certificate files are removed while the output says the shared CA remains trusted.
  7. Restore the backup if you made one: rm -rf ~/.shopify/hydrogen && mv ~/.shopify/hydrogen.bak ~/.shopify/hydrogen.

@fredericoo fredericoo changed the title Provision local HTTPS certificates automatically with a pinned mkcert Provision local HTTPS certificates automatically when running Vite with localHttps Aug 14, 2026
@fredericoo
fredericoo marked this pull request as ready for review August 14, 2026 15:00
@fredericoo
fredericoo requested a review from a team as a code owner August 14, 2026 15:00
@fredericoo fredericoo self-assigned this Aug 14, 2026

@frandiox frandiox left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice. I had seen other Vite plugins doing something similar but since we have a core feature like customer accounts, it makes sense we export one 🤔

I'm seeing this but I think it was fixed already in MiniOxygen?

Request must contain a host header.
    at toWeb (file:///...hydrogen/node_modules/.pnpm/@shopify+mini-oxygen@4.2.0_vite@8.0.10_@types+node@22.19.17_esbuild@0.28.1_jiti@2.6.1_t_33b61828dcbe09e87499152c791ecdbb/node_modules/@shopify/mini-oxygen/dist/vite/utils.js:13:11)

Comment thread packages/hydrogen/src/vite/index.ts Outdated
Comment on lines +173 to +174
try {
await provisionCertificates(settings);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a big side effect when running the Vite plugin, and I'm not sure users would notice (it modifies their system to add a certificate).

Would it make sense if we use node:readline/promises or similar to block the process until the user accepts a terminal prompt? (or exit with a nice message otherwise)

That or require a manual setup https command?

Not sure really 🤔

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i designed the API to support a setup step separately (useful for CI, as we skip interactive prompts)

but the DX obsessive in me wants to make it just work

the experience is pretty clear, there are logs all throughout the process, users know what's going on, so i'd say keep it?

  1. we can add jsdoc to the httpOnly plugin saying that by using this in vite, if enabled it will create a certificate on your machine
  2. or a prompt to get acceptance first

open to either way

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I love the "it just works" but at the same time, this is modifying the system to install a certificate... I feel this is something we should ask confirmation for. Or at least have more than 1 single step to run it: force them to enable it manually and read a comment on top of it, etc.

Alternatively... is there a command we could print to uninstall the cert we just added? Perhaps that would be good enough if someone can just undo, and give them the command when they run dev:https?
It seems there's mkcert -uninstall, and we could wire it up with extra cleaning via npx hydrogen setup https --uninstall or similar? We might need a different CAROOT for mkcert so that it doesn't uninstall different certs though 🤔

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

very interesting

i think i will do both: one confirmation dialog following the "no magic" principle we've been following, and also a way to uninstall, probably npx hydrogen certs uninstall alongside npx hydrogen certs install which just runs the script to install them

@fredericoo fredericoo Aug 20, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep, agreed - did both.

vite dev now explains the mkcert download, system trust-store change, and certificate creation before asking for confirmation. Declining makes no system changes and points to the explicit install command.

The commands are now:

  • npx hydrogen certs install
  • npx hydrogen certs uninstall removes Hydrogen's certificate files and cached binary, but leaves mkcert's shared CA trusted
  • npx hydrogen certs uninstall --remove-ca warns about other projects and then uninstalls the exact binary we installed before, not the user's main mkcert
    I kept mkcert's default CAROOT so we reuse an existing mkcert CA rather than installing another root. Removing that shared CA therefore requires the explicit flag.

@fredericoo

fredericoo commented Aug 17, 2026

Copy link
Copy Markdown
Contributor Author

Nice. I had seen other Vite plugins doing something similar but since we have a core feature like customer accounts, it makes sense we export one 🤔

I'm seeing this but I think it was fixed already in MiniOxygen?

Request must contain a host header.
    at toWeb (file:///...hydrogen/node_modules/.pnpm/@shopify+mini-oxygen@4.2.0_vite@8.0.10_@types+node@22.19.17_esbuild@0.28.1_jiti@2.6.1_t_33b61828dcbe09e87499152c791ecdbb/node_modules/@shopify/mini-oxygen/dist/vite/utils.js:13:11)

yeah i fixed it but it's not released yet

edit: now fixed in preview, using the correct minioxygen version

@fredericoo
fredericoo marked this pull request as draft August 17, 2026 18:12
@fredericoo
fredericoo force-pushed the fb-local-https-vite-plugin-mkcert branch from a5581ff to c9897c6 Compare August 17, 2026 18:21
Base automatically changed from fb-local-https-vite-plugin to preview August 18, 2026 12:50
Assisted-By: devx/07abca81-b031-4579-88c8-bc07dfd3c5aa
Assisted-By: devx/07abca81-b031-4579-88c8-bc07dfd3c5aa
Assisted-By: devx/07abca81-b031-4579-88c8-bc07dfd3c5aa
Assisted-By: devx/05def498-8bdd-48d0-bd5e-35e4667a2f3d
@fredericoo
fredericoo force-pushed the fb-local-https-vite-plugin-mkcert branch from c9897c6 to b5b5d11 Compare August 19, 2026 16:17
@fredericoo
fredericoo marked this pull request as ready for review August 19, 2026 16:22
@fredericoo
fredericoo marked this pull request as draft August 20, 2026 11:03
@fredericoo
fredericoo marked this pull request as ready for review August 20, 2026 11:18

@frandiox frandiox left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works great, thanks!

@fredericoo
fredericoo merged commit a75aba8 into preview Aug 21, 2026
5 checks passed
@fredericoo
fredericoo deleted the fb-local-https-vite-plugin-mkcert branch August 21, 2026 10:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants