This turned out to be easier than expected, but took some hunting. This solution assumes 2 things:
- your custom Obsidian domain is a subdomain that you can define in Route53
- your custom Obsidian domain does not include subdirectories (e.g.
plamo.flyinggrizzly.net
, notflyinggrizzly.net/plamo
orhobbies.flyinggrizzly.net/plamo
)
This approach uses the custom HTTP X-Header to indicate to Publish what site it’s serving.
Steps
- Choose your custom domain, like
notes.example.com
- Create a Cloudfront distribution in AWS, with these settings:
- Set the origin to
publish.obsidian.md
- Give it an alternate domain value that’s the same as your custom domain, so that it won’t error when we start routing to it from our DNS
- Assign an SSL cert (this might be one you already have, if you have a wildcard cert for subdomains like
*.example.com
) - Set a custom header, with a name of
X-Obsidian-Custom-Domain
and a value ofnotes.example.com
(/replace with your custom domain)
- Set the origin to
- In Route53, add a DNS CNAME entry for your subdomain, pointing at your Cloudfront distro’s URL (be sure to remove the
https://
if you used the “Copy” button on the distribution page) - Set your custom domain in the Obsidian Publish config settings
Give the DNS and CDN a minute to propagate, and you should now be able to access your published notes at your custom domain.
Other configurations
Obviously, the above is assuming you are using a subdomain without subdirectories.
I suspect this would work for a sub-folder, either by including that in the X-Header’s value, or firing a Lambda@Edge function on Viewer Request events.
The lambda could be used to rewrite your request URIs and get finer-grained control over the path patterns if there’s a mismatch between your filepaths in Obsidian and the request URLs being handled by Cloudfront. Something like this (not tested!):
// Running on Node 14.x runtime
exports.handler = (event, context, callback) => {
const OBSIDIAN_CUSTOM_BASE_DOMAIN = 'example.com'
const request = event.Records[0].cf.request
// Identify the requested note resource path
const path = request.uri
// Update the request URI to hit Publish's serve endpoint
request.uri = '/serve'
request.querystring = `url=${OBSIDIAN_CUSTOM_BASE_DOMAIN}${path}`
return callback(null, request)
};