Skip to content

Export Ghost Blog to Static HTML: No Node or wget Needed

Export Ghost blog to static HTML with no Node, wget or local Ghost install. Compare the JSON export and a browser crawl, and see what breaks offline.

Website Downloader 9 min read

Ghost Admin has no “export Ghost blog to static HTML” button. Its built-in export is a JSON file of your posts and settings, meant for importing into another Ghost install, not for reading. To get a browsable copy you have two routes. You can run developer tools such as gssg or wget against the blog, or you can crawl the published site from your browser and receive every post, tag page, image and stylesheet as one ZIP. On Ghost(Pro), where you don't run Ghost locally, the browser crawl is the only route that needs nothing installed.

Does Ghost have a built-in HTML export?

No. Under Settings → Advanced → Import/Export (the exact menu name has moved between Ghost versions), Ghost gives you a content export. That is a single .json file containing posts, pages, tags, authors and site settings. Elsewhere in the admin you can download your active theme as a ZIP and your members as a CSV file.

All three are useful, but none of them is a website. Double-click the JSON file and you see raw data, with post bodies stored as markup inside text fields. The theme ZIP holds Handlebars templates that need Ghost to render them. Nothing Ghost exports opens as a working blog in a browser, and that is why people end up looking for a static copy.

Ghost JSON export vs an HTML copy: which one do you need?

They do different jobs, and for a serious backup you usually want both.

Ghost JSON exportStatic HTML copy
What it isYour content as structured dataThe rendered site: HTML, CSS, JS, images, fonts
Opens in a browserNoYes, offline
Includes imagesNo, only their URLsYes, the images shown on public pages
Includes your theme's lookNoYes, exactly as published
Re-importable into GhostYesNo
Includes members-only contentYes, the full post bodyOnly what a logged-out visitor sees
Hostable on a static hostNoYes

Rule of thumb: moving to another Ghost install? Use the JSON export, plus the images and the members CSV. Want a readable archive, a frozen site on GitHub Pages or Netlify, or proof of what the blog looked like? You need the HTML copy. Leaving Ghost(Pro) for good? Take both. The JSON keeps your words in a structured form for whatever platform comes next, and the HTML copy keeps the blog readable with its images and design.

One detail catches people out. The JSON export does not contain images. Posts point to paths such as /content/images/2023/05/photo.jpg on your Ghost server. Ghost(Pro) has no file manager for downloading that folder, so if you need the original image files, ask Ghost support before you cancel. A static HTML copy collects the images that appear on your public pages as part of the crawl.

How to export Ghost blog to static HTML in the browser, with nothing to install

This route suits Ghost(Pro) users and anyone who doesn't want Node.js, Python or a local copy of Ghost on their machine. It also avoids the localhost problem described further down: the crawl runs against your live public domain, so no URL ever pointed at localhost in the first place.

  1. Open the blog in a private window first. This shows you exactly what an anonymous visitor sees. Whatever needs a login won't appear in the copy either.
  2. Enter your blog's address, for example https://yourblog.com, in the download field on the Website Downloader home page and start the download.
  3. Watch the progress. The crawl follows links from the home page into posts, pages, tag archives, author pages and paginated lists such as /page/2/. A live counter shows how many pages it has found. You can close the tab, because the crawl doesn't need your computer to stay on.
  4. Download the ZIP, unpack it and open index.html. Click through a few posts, a tag page and the second page of the home feed to check the result.
Enter the blog's public address, let the crawl count through posts, tags and pagination, and download a single ZIP that opens offline.

How many pages is your Ghost blog? Count more than your posts. Every tag gets an archive page, every author gets one, and long lists are split across numbered pages. A blog with 60 posts, 15 tags and paginated archives can pass 100 pages. The free plan covers up to 100 subpages with no account. A one-time Single Site download covers up to 5,000 subpages and keeps the archive for 30 days. Details are on the pricing page.

If your Ghost blog is already offline, for example because a Ghost(Pro) subscription lapsed, a crawl of the live site is no longer possible. The Wayback Machine downloader can rebuild it from Internet Archive captures, provided the archive captured it. The walk-through is in our guide to restoring a site from the Wayback Machine.

Developer tools: gssg, Buster and wget --mirror, and where they break

Most tutorials that rank for this topic assume you run Ghost on your own machine and are comfortable in a terminal. The tools they recommend:

  • gssg (ghost-static-site-generator) is a Node package that wraps wget. You point it at a running Ghost instance, usually http://localhost:2368, and it writes a static folder. Flags let you replace the local address with your production domain. It works, but it needs Node, wget and a local Ghost that matches your live content.
  • Buster is an older Python tool built on the same idea. It is no longer maintained, and its own demo site has shown the classic symptom: links still pointing to localhost.
  • ghost-static and similar small projects describe themselves as unmaintained. Treat them as starting points for reading code, not as tools to trust with your only archive.
  • Plain wget is the most dependable of the scripted options. It needs no Ghost-specific wrapper:
    wget --mirror --convert-links --adjust-extension --page-requisites --no-parent https://yourblog.com/
    It can crawl your live Ghost(Pro) site directly, but you have to install it, tune it and then clean up its output.

The Ghost forum's usual answer, rebuilding the front end with Eleventy or another static generator that reads from the Content API and deploys to Netlify, is a good long-term setup if you plan to keep publishing. It is a rebuild with a new theme, not a copy of your existing site. For a side-by-side look at the command-line and browser approaches, see wget vs HTTrack vs an online website downloader.

Why do links or images point to localhost after a static export?

A Ghost instance writes its configured URL into absolute links. On a local install that URL is http://localhost:2368, and it ends up in canonical tags, Open Graph images, srcset attributes, the sitemap and the RSS feed. Crawl that instance and every one of those references points to your own computer. On your laptop the site looks fine, because Ghost is running. After deployment, images and links break for everyone else.

The second trap is asset query strings. Ghost themes load files such as /assets/built/screen.css?v=3f2a1c. Depending on its settings, wget may save that file with the ?v=… part inside the filename. A static host then looks for screen.css, finds nothing and serves the page without styles. The same can happen to theme JavaScript and fonts.

A pre-deploy check that takes five minutes

  1. Search the folder for localhost. On macOS or Linux run grep -rl "localhost" . inside the unpacked folder. On Windows use a text editor's “find in files”. Every hit is a link that will break.
  2. Look for odd filenames containing ?, %3F or @ in the assets folder. They point to the query-string problem.
  3. Test offline. Switch off Wi-Fi and open index.html. Missing styles or images show you which references still depend on the network.
  4. Check three page types: a long post with images, a tag archive and /page/2/. Those are where gaps usually show up.

If something is missing, our guide to fixing downloads with missing images and CSS goes through the causes one by one.

What a static Ghost copy can't do: members-only posts, Portal sign-up, search and comments

Ghost is more than a set of pages. Several features depend on Ghost's server and its APIs, and a static copy of any kind, from any tool, cannot keep them working:

  • Members-only and paid posts. A logged-out visitor sees the preview and the call to subscribe, not the full post. A crawl sees the same, so the copy contains the teaser only. The full text of those posts lives in your JSON export.
  • Portal. The sign-up and sign-in pop-up and the account page need Ghost's membership backend. In the copy the buttons may still appear, but they do nothing.
  • Newsletter sign-up forms post to Ghost and fail without it.
  • Search. Ghost's search queries the Content API on the fly. Offline, nothing comes back.
  • Native comments load from Ghost and need a signed-in member. Third-party comment widgets need their provider's server.
Posts, pages, images, fonts and theme styles survive in a static Ghost copy. Membership sign-up, search, forms and comments need Ghost's server and stop working.

For an archive, that is usually acceptable: the writing, the images and the design are what you want to keep. For a site that should keep collecting subscribers, replace the sign-up form with an embed from a newsletter service, or link out to wherever your list now lives.

Can I host an exported Ghost blog on GitHub Pages, Netlify or S3?

Yes. A static Ghost copy is plain files, so any static host can serve it:

  • GitHub Pages: unpack the ZIP into a repository, push it, enable Pages for the branch and add your custom domain in the settings. Check the localhost search above first, because GitHub serves whatever is in the repository.
  • Netlify: drag the unpacked folder onto the deploy area. This is the fastest way to see a frozen Ghost site live on a test URL.
  • Amazon S3: upload the files to a bucket, turn on static website hosting with index.html as the index document, and put a CDN in front if you want HTTPS on your own domain.
Freezing a Ghost blog: crawl it while it is still live on Ghost(Pro), keep it as one ZIP, then deploy the unpacked folder to any static host.

Leaving Ghost(Pro) with a readable archive

Order matters, because once the subscription ends there is nothing left to crawl:

  1. Export the JSON content file, the members CSV and the theme ZIP from Ghost Admin.
  2. Ask Ghost support about your original image files if you need them in full resolution.
  3. Create the static HTML copy while the blog is still live and check it with the steps above.
  4. Deploy the copy to its new host and test it on a temporary URL.
  5. Point your domain at the new host, then cancel Ghost(Pro).

The same freeze-then-host pattern works for other platforms. If you also run a WordPress site, see converting WordPress to static HTML.

FAQ

Does the Ghost JSON export include images?

No. It contains your text, tags, authors and settings, and it refers to images only by their URLs on your Ghost server. A static HTML copy does include the images shown on your public pages. For the original files from Ghost(Pro), ask Ghost support.

Can I export a Ghost(Pro) blog without running Ghost locally?

Yes. Crawl the live public site, either with a browser-based tool such as Website Downloader or with wget pointed at your real domain. Because the crawl uses your production URL, the localhost-link problem from local exports doesn't arise.

Are members-only or paid posts included in a static copy?

Only the public part. A crawler sees what a logged-out visitor sees, which is the preview and the subscribe prompt. Pages behind a login are not downloaded. Your JSON export holds the full text of those posts.

Do Ghost search, comments and newsletter sign-up work in a static copy?

No. Search, Portal, sign-up forms and comments all rely on Ghost's server and APIs. The pages around them still display, but those features stop responding. The FAQ covers what offline copies can and can't do in general.

How do I keep the archive up to date if I keep publishing?

A static copy is a snapshot of one moment. Run a fresh download after each batch of posts, or monthly if you publish often, and replace the old copy on your static host. If you want a static site that updates itself, a Content API setup with a static generator is the better fit than repeated snapshots.

  • export Ghost blog to static HTML
  • Ghost
  • static HTML
  • website backup
  • site migration