Make your baseURL the top domain (https://www.example.com/),
For your page images and pages, nothing changes
For your static assets, use a relative permalink and prepend your CDN (e.g. if you are generating your CSS to /public/assets/css, then the .RelPermalink would be /assets/css. If you concatenate https://cdn.example.com to /assets/css you’d get https://cdn.example.com/assets/css/somecss.css (for each css file, and according to your dir structure, that is).
Use some script to copy or static resources where they belong on the CDN vs everything else that goes on the main server.
I don’t think there is, however, an automated way to do this.
There is a multilingual multihost option, but that is a different beast.
I tried that, but unfortunately it breaks the third scenario I listed - “Still have relative image links in Markdown with the local hugo server command working as usual”.
It is also nice to be able to open a page bundle locally in a markdown preview app (I use Marked 2)
Ah, for that I would wrap the asset link generation in {{ if eq hugo.Environment 'development' }}, e.g. (based on the new theme skeleton’s CSS layout):
{{- if eq hugo.Environment "development" }}
<link rel="stylesheet" href="{{ .RelPermalink }}">
{{- else }}
{{- with . | minify | fingerprint }}
<link rel="stylesheet" href="{{ site.Params.cdnURL }}{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" crossorigin="anonymous">
{{- end }}
{{- end }}
For images you could use a render-image render hook. If there are other links you need to modify, you’d need to conditionally modify a render-link render hook.