# Create React App

Builds to build/ and almost always needs --spa.

Create React App builds to `build/`. It produces one `index.html` and routes in
the browser, so it needs `--spa`.

```console title="create react app"
$ npm run build
Creating an optimized production build...
Compiled successfully.
$ one9x pages release ./build --site myapp --spa --deploy
✓ v1 live · unknown routes → /index.html
→ https://myapp.one9x.app/
```

## homepage in package.json

If `package.json` has a `"homepage"` pointing at a subdirectory — a leftover
from GitHub Pages — the build writes asset URLs under that path and the site
loads blank with 404s on every script.

On a One9x site you are at the root of your own subdomain. Remove `homepage`, or
set it to `"/"`, and rebuild.

## Source maps

CRA emits source maps by default, which publishes readable source alongside the
bundle. Either turn them off at build time:

```console title="no source maps"
$ GENERATE_SOURCEMAP=false npm run build
```

or leave them out of the release:

```console title="exclude them instead"
$ one9x pages release ./build --site myapp --spa --deploy --exclude '*.map'
9 path(s) excluded
✓ v2 live
```

> Create React App is no longer maintained upstream. It still builds and still
> deploys — nothing here changes — but if you are starting something new,
> [Vite](/docs/frameworks/vite) is the direct replacement and the deploy command
> is identical.

## Start from a template

Live, and deployed by the workflow in that repo on every push:
**[create-react-app.one9x.app](https://create-react-app.one9x.app/)**.

[`one9x/template-create-react-app`](https://github.com/one9x/template-create-react-app) is a minimal Create React App starter
with this deploy already wired up. Press **Use this template** on GitHub to get
your own copy, or read it as a reference for a project you already have.

Set two things in the new repo under **Settings → Secrets and variables →
Actions** and it deploys on every push:

| | Name | Value |
| --- | --- | --- |
| Variable | `ONE9X_SITE` | the site to deploy to |
| Secret | `ONE9X_TOKEN` | `one9x tokens create "github actions"` |

Until `ONE9X_SITE` is set the workflow is skipped rather than failed — a fresh
copy should not open with a red X.

## Deploying on every push

```yaml
- uses: actions/setup-node@v5
  with: { node-version: 22, cache: npm }
- run: npm ci
- run: npm run build
  env:
    GENERATE_SOURCEMAP: 'false'
- uses: one9x/pages-deploy@v1
  with:
    site: myapp
    dir: build
    spa: true
    token: ${{ secrets.ONE9X_TOKEN }}
    deploy: ${{ github.ref == 'refs/heads/main' }}
```