tools / repair

ZIP root flattener

The builder copes with one wrapping folder on its own. What it cannot guess is which of several folders is your site — zip a whole project and it may open the development template instead of the build. This lists every candidate, lets you pick, and rebuilds the ZIP with that folder's index.html at the top.

Flatten a ZIP

Every folder in the archive that contains an index.html is listed. Pick the one that is your site; its contents become the root of the new ZIP.

Drop your site ZIP here, or click to choose .zip · opened in this tab, never uploaded

How the builder picks the start page

When a ZIP is uploaded, the builder decides which page the app opens with, in this order:

  1. index.html at the top of the archive, if there is one;
  2. otherwise, if everything sits inside one folder, that folder's index.html — the folder is stripped off, which is why "I compressed the folder instead of its contents" usually just works;
  3. otherwise, the shallowest HTML file it can find.

Rule three is where things go wrong. Zip a whole framework project and the shallowest HTML file is the index.html template in the project root — which loads uncompiled source and shows a blank page — not the real one in dist/. Zip a repository with a docs/ site and a demo/ page and you get whichever path is shorter. Flattening removes the guesswork: the page you choose becomes the only candidate.

The three ways a ZIP ends up nested

How it happenedWhat the archive looks likePick this folder
You compressed the folder rather than its contentsmy-site/index.htmlmy-site/
You zipped a whole framework projectmy-app/src/…, my-app/dist/index.htmlmy-app/dist/ (or build/, out/)
You downloaded a repository from GitHubrepo-main/docs/index.htmlthe folder GitHub Pages served

When a project ZIP contains both the source and a build folder, this tool pre-selects the build folder (dist, build, out, public, www, docs). The source index.html of a Vite or React project is a template that loads uncompiled code; the app needs the compiled one.

What gets copied

Everything inside the folder you pick, with its internal structure unchanged, so every relative link in your pages keeps working. Anything outside that folder — the source code, package.json, the README — is left out. File dates are preserved. Nothing is uploaded: the new ZIP is assembled in this tab and downloaded directly.

Doing it by hand next time

Open the folder that contains index.html, select everything inside it (Ctrl/⌘ + A), and compress the selection. On the command line: cd dist && zip -r ../site.zip . — the trailing dot is what keeps the folder name out of the archive.

Frequently asked questions

My ZIP has one folder with the site inside — do I need this tool?

No. The builder strips a single wrapping folder automatically. You need the flattener when the archive holds more than the site: source plus a build folder, several demos, or a repository download.

My ZIP has index.html at the root but the app still opens the wrong page — why?

Check the file name's case and extension. Index.html, index.htm and index.HTML are all different files to Android. Rename it to exactly index.html.

Can the start page be called something other than index.html?

Keep it index.html. If your site's real start page is home.html, the simplest fix is a one-line index.html that redirects: <meta http-equiv="refresh" content="0; url=home.html">.

Will flattening break my links?

No. Everything inside the chosen folder keeps its position relative to everything else, so relative links (css/style.css, ../img/logo.png) resolve exactly as before. Only root-relative links that start with / would need attention, and they needed it anyway.

Read in the docs

Related tools

Unzip it on a phone today

Upload the ZIP, name the app, pick an icon — and download a signed APK a few minutes later. Free builds, no watermark, no Android Studio.

Convert a ZIP — free site.zip → app-release.apk