# Leaving files out

> For the complete documentation index, see [llms.txt](https://preview.writedocs.io/llms.txt).

The .wdignore file - which files of a project are never published or read as content, the files left out by default, and how to bring one back.

A docs project often shares its folder with things that aren't the site: a `package.json`, a `.env`, an export with customer data. Writedocs leaves a list of such files out by default, and a `.wdignore` file at the project root lets you add your own - or bring a default one back.

A file that's left out is never published and never read as content: it isn't [published at its own path](https://preview.writedocs.io/docs/project-structure/#other-files), it isn't a page, its CSS or JavaScript isn't loaded, and an image in it isn't shown.

## The `.wdignore` file

Create a file named `.wdignore` next to `writedocs.json`, with one pattern per line. The syntax is the one `.gitignore` uses:

```text title=".wdignore"
# Drafts and internal material
drafts/
internal-notes.md

# Every CSV, except the public ones
*.csv
!data/public/*.csv
```

| Pattern | What it leaves out |
| --- | --- |
| `drafts/` | Every folder named `drafts`, at any depth, and everything in it. |
| `/drafts/` | Only the `drafts` folder at the project root. |
| `internal-notes.md` | Every file (or folder) with that name, at any depth. |
| `docs/guides/old.mdx` | That one file. A pattern with a `/` in the middle starts at the project root. |
| `*.csv` | Every file ending in `.csv`. `*` doesn't cross a `/`. |
| `data/**/*.csv` | Every `.csv` under `data/`, at any depth. |
| `!data/public/*.csv` | Brings back what an earlier line left out. |
| `# ...` | A comment. Blank lines are skipped too. |

Later lines win over earlier ones, and upper and lower case are treated as the same.

> **A file can't come back while its folder is left out**
>
> As in `.gitignore`: once a folder is left out, a `!` line for a file inside it does nothing. Bring the folder back (`!drafts/`), then leave out what you don't want in it.

`writedocs dev` picks up a change to `.wdignore` without a restart.

## What's left out by default

These apply to every project, with or without a `.wdignore`.

### Never published

Secrets. No `.wdignore` line brings these back, and they're left out of the `public/` folder too:

| Pattern | What it is |
| --- | --- |
| `.env`, `.env.*` | Environment files - API keys and passwords. |
| `.git/` | The repository's history. |
| `.npmrc` | Package manager configuration, which can hold an access token. |
| `*.pem`, `*.key`, `*.p12`, `*.pfx` | Private keys, and the files that carry them. |
| `id_rsa*`, `id_dsa*`, `id_ecdsa*`, `id_ed25519*` | SSH keys. |

### Left out unless you bring them back

Tooling and data that a docs repository holds but a site rarely means to publish. A `!` line in `.wdignore` brings one back:

| Pattern | What it is |
| --- | --- |
| `.*` | Every file and folder whose name starts with a dot: `.gitignore`, `.gitmodules`, `.gitattributes`, `.github/`, `.vscode/`, `.DS_Store`, `.wdignore` itself, `.writedocs/` ... |
| `package.json`, `package-lock.json`, `yarn.lock`, `pnpm-lock.yaml`, `bun.lockb`, `bun.lock`, `composer.json`, `composer.lock` | Package manifests and lockfiles. |
| `node_modules/`, `dist/` | Dependencies and build output, at any depth. |
| `tsconfig.json`, `jsconfig.json`, `vercel.json`, `netlify.json`, `netlify.toml`, `wrangler.json`, `wrangler.jsonc`, `wrangler.toml`, `Dockerfile`, `docker-compose*.yml`, `docker-compose*.yaml` | Tooling and hosting configuration. |
| `*.crt`, `*.jks`, `*.keystore` | Certificates and key stores. |
| `*.sqlite`, `*.sqlite3`, `*.db`, `*.sql` | Databases and dumps. |
| `*.log` | Logs. |

Each one applies at any depth: `examples/app/package.json` is left out like the one at the root.

## Bringing a default back

Some of these are sometimes real content - a `package.json` a guide walks through, a SQL file to download, a `.well-known/` folder. Add a `!` line:

```text title=".wdignore"
# The example app's manifest, for readers to download
!examples/app/package.json

# A folder whose name starts with a dot
!.well-known/

# The built example, zipped
!examples/app/dist/
```

Bringing a file back makes it a file like any other, so the usual rule still decides whether it's published: it is when it's one of the [kinds of file Writedocs publishes](https://preview.writedocs.io/docs/project-structure/#other-files). `!.well-known/` publishes `.well-known/security.txt`, and `!examples/app/package.json` publishes that file. A `.sql` file isn't one of those kinds - to offer one for download, put it in [`public/`](#the-public-folder), where it's published without a `.wdignore` line.

Three things don't come back:

- The files under [Never published](#never-published).
- `node_modules/`, `dist/` and `.writedocs/` at the project root.
- Pages, CSS and JavaScript inside a folder whose name starts with a dot. `!.drafts/` publishes the PDFs and images in `.drafts/`, but an `.mdx` file there still isn't a page.

## The `public` folder

Everything in a `public/` folder is published as it is - putting a file there already says "publish this". So the defaults under [Left out unless you bring them back](#left-out-unless-you-bring-them-back) don't apply inside it: `public/.well-known/security.txt` and `public/downloads/schema.sql` are published with no `.wdignore` at all.

Two things still apply in `public/`:

- The files under [Never published](#never-published). A `public/.env` or `public/server.key` is not published.
- Your own `.wdignore` lines. A pattern matches the file's path from the project root, so `public/old/` leaves that folder out.

## Links to a file that's left out

A page can still name a file that's left out - link to it, or show it as an image. The build doesn't fail: the file just isn't on the site, so the link leads nowhere and the image doesn't load.

[`writedocs broken-links`](https://preview.writedocs.io/docs/cli/#writedocs-broken-links) finds these, and says why:

```text
index.mdx
  12  /internal/plan.pdf - internal/plan.pdf is in the project, but the ignore rules leave it out, so it isn't published.
      To publish it, bring it back in .wdignore - a line with !internal/plan.pdf, or its folder's (!folder/) when the whole folder is left out.
```

## What to keep in mind

- **Don't leave out a file the site is built from.** A [snippet](https://preview.writedocs.io/docs/content/snippets/) a page imports, or the OpenAPI spec an [API reference](https://preview.writedocs.io/docs/openapi/overview/) reads, has to be there when the site is built - with one of them left out, the build fails. [`writedocs broken-links`](https://preview.writedocs.io/docs/cli/#writedocs-broken-links) reports a page that imports a snippet that's left out. `writedocs.json` is always read and never published, whatever `.wdignore` says.
- **A page that's left out has no address.** If `writedocs.json`'s navigation still lists it, [`writedocs validate`](https://preview.writedocs.io/docs/cli/#writedocs-validate) reports the missing page.
- **It decides what's published, not what's in your repository.** A secret that's committed is still in the repository's history. `.wdignore` keeps it off the site.
- **`.mintignore` still works.** A project that came from Mintlify keeps its `.mintignore`, which lists files that aren't pages. `.wdignore` does that too, and also covers every other file - use it for anything new.