Copied!
Blog

How to Download a Website for Offline Use (and Why Modern Sites Break)

Save Page As, SingleFile, wget and HTTrack compared on real modern sites, why the copy opens blank or unstyled, and how to fix it.

← Blog
Earth at night seen from space with glowing city lights
Photo via Unsplash

October 14, 2026

5 min readIncludes a tool comparison and copy-ready commands

Downloading a website used to be easy. Pages were HTML files, images and a stylesheet, and any downloader could follow the links and copy them. Today you can run a perfectly good downloader, open the result, and get a white page, a page with no fonts, or a hero with a black rectangle where the 3D used to be.

This guide covers the right tool for each job, then explains the three reasons modern sites break offline and how to fix each one.

Pick the right tool for the job

Start with what you need. Reading one article on a plane is a different job from archiving a client’s whole site or studying how an animated page was built.

One page, for reading: Save Page As or SingleFile

For an article, a recipe or documentation, you do not need anything heavy.

On a phone, Safari’s Reading List saves pages for offline reading on iPhone, and Chrome’s download button does the same on Android. Both are for reading, not for keeping a working copy.

A whole site: wget or HTTrack

To mirror many pages, use a crawler. wget is on most Macs (via Homebrew) and Linux machines, and in WSL on Windows:

wget --mirror --convert-links --adjust-extension \
     --page-requisites --no-parent https://example.com/docs/

Add --wait=1 to be polite to the server. Fetching hundreds of pages as fast as possible is how you get rate-limited or blocked. HTTrack does the same job with a graphical interface on Windows, and the command-line version works anywhere:

httrack https://example.com/docs/ -O ./example-mirror

Both are excellent for documentation, blogs and server-rendered sites. Both share one blind spot, covered next.

Why modern sites break offline

Open a wget mirror of a React, Next.js or Webflow site and you will often see one of three failures. They have different causes, so it helps to know which you are looking at.

THREE WAYS AN OFFLINE COPY FAILS (blank page) 1. Blank page The HTML is an empty shell. Content comes from JS chunks a crawler never saw requested. FIX: capture after JS runs Big Headline img? 2. No fonts, no images Files live on other domains, load lazily on scroll, or are requested from JavaScript. FIX: span hosts, load lazy file:///C:/site/index.html Blocked by CORS policy origin 'null' 3. Opened as a file Browsers block module scripts, fetch() and some fonts on file:// URLs. Nothing is missing. FIX: serve on localhost
Failure 3 is the most common, and the easiest to fix. Try it before re-downloading anything.

1. The page is built by JavaScript

wget and HTTrack read HTML and follow links. They never run scripts. On a single-page app the HTML is little more than <div id="root"> and a script tag. Worse, modern bundlers split code into chunks the page requests only while running (import() calls), so the crawler never even learns those files exist. The fix is to capture the page in a real browser after it has run.

2. Assets live elsewhere, or load late

Fonts often come from a font CDN, images from an image CDN, and 3D models from a storage bucket, all on different domains. wget skips other hosts unless you add --span-hosts with a --domains list. Lazy-loaded images only request their real source when scrolled into view, which a crawler never does. And files requested from JavaScript (a texture, a JSON scene) are invisible to anything that does not run the page.

3. You opened it as a file

This one catches almost everyone. Double-clicking index.html opens it as file://. Browsers treat that as a special, locked-down origin: ES module scripts, fetch() calls and some font loads are blocked by CORS. The site looks broken even though every file is present. Serve the folder instead:

cd example-mirror
npx serve .            # or: python -m http.server 8000

Then open the localhost address it prints. We wrote up a real case, where a captured Webflow + GSAP site looked broken until it was served properly, in why a captured site looks broken until you stop opening it as a file.

Capturing the page as it actually runs

For sites built mostly from JavaScript (anything with real animation, WebGL, or a React front end), the reliable approach is to record what a real browser loads while the page runs, rather than guess from the HTML. That is what a runtime capture does. Enrichr loads the page in a browser, scrolls it so lazy assets fire, records every request (chunks, fonts, textures, models), rewrites the URLs to local paths and packages the result as a zip.

Two honest caveats. First, any running copy still needs to be served on localhost, for the reasons in failure 3. Second, anything that depends on a live backend (logins, search, checkout, personalised content) cannot work offline in any copy, because the server that answered those requests is not in the zip.

A quick decision guide

You want to…Use
Read an article on a planeSingleFile, Save Page As, or your phone’s reading list
Keep a record of how a page lookedSingleFile (one file, opens anywhere) or a full-page screenshot
Mirror docs or a blogwget --mirror or HTTrack
Study an animated or 3D site offlineA runtime capture, served on localhost
Rebuild a site you no longer have the source forA runtime capture plus recovered source maps (workflow)

Whatever you use, keep downloads for your own use. Republishing someone else’s site is a different matter, covered in is it legal to copy a website design?

FAQ

How do I download an entire website for offline viewing?

Use wget with --mirror --convert-links --page-requisites --adjust-extension --no-parent, or HTTrack’s GUI on Windows. Both follow links and save each page with its CSS and images. JavaScript-built content may still be missing.

Why does my downloaded website look broken?

Usually one of three reasons: the content is built by JavaScript that did not run or could not load, files on other domains (CDNs, font hosts) were not downloaded, or you opened the copy as a file:// URL, which blocks modules, fetch requests and some fonts. Serving the folder on localhost fixes the third.

How do I download a website for offline use on Chrome?

For one page: press Ctrl+S (Cmd+S on Mac) and choose “Webpage, Complete”, or install the SingleFile extension for a cleaner single-file copy. For a whole site, use wget or HTTrack instead.

How do I save a website for offline use on iPhone or Android?

On iPhone, add pages to Safari’s Reading List, which saves them for offline reading, or share them as PDFs to the Files app. On Android, open Chrome’s menu and tap the download icon to save a page. Neither keeps interactivity.

Is it legal to download a website?

Saving pages for your own offline reading is generally fine. Republishing the copy, or ignoring a site’s terms and robots rules with aggressive crawling, is not. See is it legal to copy a website design for the details.