Skip to content

Comments

Added ghost-cdn-url meta tag and fixed ././ build output#26555

Open
rob-ghost wants to merge 1 commit intomainfrom
feat/ghost-cdn-url-meta-tag
Open

Added ghost-cdn-url meta tag and fixed ././ build output#26555
rob-ghost wants to merge 1 commit intomainfrom
feat/ghost-cdn-url-meta-tag

Conversation

@rob-ghost
Copy link
Contributor

@rob-ghost rob-ghost commented Feb 24, 2026

Summary

  • Added a <meta name="ghost-cdn-url"> tag and bridge script to apps/admin/index.html that propagates a CDN URL into Ember's config meta tag at runtime
  • Fixed vite-ember-assets plugin reading from the combined output directory instead of the Ember dist, which caused ././assets/ path prefixes to accumulate on repeated builds

Background

Ghost(Pro) currently bakes absolute CDN URLs into the admin build at CI time via GHOST_CDN_URL, then string-replaces them per environment at deploy time. The new cd.yml flow (Ghost-Moya #135, merged) replaces this with a simpler approach: build once with relative paths, then rewrite only index.html at deploy time with sed. A meta tag provides the CDN URL to Ember's runtime config, and static asset refs are rewritten to point at the CDN.

This PR adds the meta tag infrastructure. It's a no-op until a relative-path artifact is deployed through cd.yml.

Details

ghost-cdn-url meta tag: The bridge script reads the meta tag's content attribute and, if non-empty, injects the value into Ember's URL-encoded config meta tag as cdnUrl. When content="" (self-hosted, local dev, current CI), the script does nothing. The tag only becomes active after a deploy-time sed populates it with a CDN URL.

././ fix: The vite-ember-assets plugin was reading Ember asset paths from ghost/core/core/built/admin/index.html — the combined output directory that gets overwritten by the plugin's own closeBundle hook. On each build, paths that already had ./ got another ./ prepended. Now reads from ghost/admin/dist/index.html (the Ember build's own output), producing clean ./assets/ paths. This is necessary for the sed replacement to work with a single consistent pattern.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 24, 2026

Walkthrough

The pull request introduces a CDN URL propagation mechanism and adjusts Ember admin asset loading. In the admin index file, a meta tag reads a CDN URL on load, finds Ghost admin metadata, decodes its JSON content, sets the cdnUrl property, re-encodes the data, and updates the meta tag. Additionally, the Vite Ember assets plugin is modified to read the admin index.html from the Ember build output directory instead of the Ghost admin built path, with a new constant introduced for the Ember distribution directory.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title refers to two concrete changes in the changeset: the ghost-cdn-url meta tag addition and the vite-ember-assets plugin fix, which are the main objectives of the PR.
Description check ✅ Passed The description provides a comprehensive explanation of both changes, their purpose, and the background context, clearly relating to the actual changeset modifications.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/ghost-cdn-url-meta-tag

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

The ghost-cdn-url meta tag and bridge script enable deploy-time CDN URL
injection via a single sed command. The bridge script propagates the CDN
URL into Ember's config meta tag before Ember boots — no-op when empty.

Also fixed vite-ember-assets plugin reading from the combined output
directory (built/admin/) instead of the Ember dist, which caused ././
path prefixes to accumulate on repeated builds. Now reads from
ghost/admin/dist/ directly and produces clean ./assets/ paths.
@rob-ghost rob-ghost force-pushed the feat/ghost-cdn-url-meta-tag branch from 306170c to e5a2df9 Compare February 24, 2026 14:44
@rob-ghost rob-ghost marked this pull request as ready for review February 24, 2026 14:57
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
apps/admin/index.html (1)

17-30: Guard decode/parse to avoid hard failure on malformed meta content.

If the env meta tag is ever malformed (e.g., partial rewrite), decodeURIComponent/JSON.parse will throw and can stop the script. A small guard keeps the boot resilient.

🔧 Suggested defensive guard
     (function() {
       var c = document.querySelector('meta[name="ghost-cdn-url"]');
       if (c && c.content) {
         var m = document.querySelector('meta[name="ghost-admin/config/environment"]');
         if (m) {
-          var d = JSON.parse(decodeURIComponent(m.content));
-          d.cdnUrl = c.content;
-          m.content = encodeURIComponent(JSON.stringify(d));
+          try {
+            var d = JSON.parse(decodeURIComponent(m.content));
+            d.cdnUrl = c.content;
+            m.content = encodeURIComponent(JSON.stringify(d));
+          } catch (e) {
+            // no-op: keep original content if malformed
+          }
         }
       }
     })();
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/admin/index.html` around lines 17 - 30, Guard the decode/parse of the
env meta content to avoid hard failures: in the inline IIFE that queries meta
elements (variables c and m) and reads m.content, validate m.content is present
and wrap the decodeURIComponent + JSON.parse steps in a try/catch (or
conditional check) so malformed or empty content is skipped; only set d.cdnUrl
and update m.content if parsing succeeds, and log or silently ignore parse
errors to keep the boot resilient.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@apps/admin/index.html`:
- Around line 17-30: Guard the decode/parse of the env meta content to avoid
hard failures: in the inline IIFE that queries meta elements (variables c and m)
and reads m.content, validate m.content is present and wrap the
decodeURIComponent + JSON.parse steps in a try/catch (or conditional check) so
malformed or empty content is skipped; only set d.cdnUrl and update m.content if
parsing succeeds, and log or silently ignore parse errors to keep the boot
resilient.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1dc579a and e5a2df9.

📒 Files selected for processing (2)
  • apps/admin/index.html
  • apps/admin/vite-ember-assets.ts

<meta name="ghost-cdn-url" content="">
<script>
(function() {
var c = document.querySelector('meta[name="ghost-cdn-url"]');
Copy link
Member

Choose a reason for hiding this comment

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

Where are we setting the ghost-cdn-url meta tag?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So it works, but its kind of backwards for now.

We build with GHOST_CDN_URL which puts the value in ember's meta config (URL encoded). ghost-cdn-url is empty by default, so the bridge leaves the ember meta config alone.

If we set ghost-cdn-url by doing the string replacement, this overrides the existing build value.

The string replacement takes place during deploy depending on the environment we're deploying to: https://github.com/TryGhost/Ghost-Moya/pull/135

A different approach might be to move the GHOST_CDN_URL handling to this new meta tag and overwrite it with the replacement. Then ghost-cdn-url becomes the source-of-truth.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants