> For the complete documentation index, see [llms.txt](https://docs.hollaex.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.hollaex.com/advanced/customizing-your-frontend-projects-with-hollacloud-json.md).

# Customizing Your Frontend Projects with hollacloud.json

When you host a website on HollaCloud, you can control how it routes traffic — redirects, rewrites, custom headers, and trailing slashes — by adding a single file called `hollacloud.json` to your project. If you've used `vercel.json` before, this will feel right at home.

You don't need this file for a normal site. It's only there for when you want to customize routing.

### Adding the file

1. Create a file named `hollacloud.json` in the **root of your project** (the same folder as your `package.json`, `index.html`, or `hugo.toml`). For a monorepo, place it at the root of the project path you publish.
2. Add your rules (see the examples below).
3. **Republish** your project from the dashboard — your config is applied on every publish.

{% hint style="info" %}
Changes only take effect after you republish. Editing the file in your repo isn't enough on its own.
{% endhint %}

### A quick example

Here's a minimal file that sends visitors from an old URL to a new one:

```json
{
  "redirects": [
    {
      "source": "/old-pricing",
      "destination": "/pricing"
    }
  ]
}
```

Every section is optional, so you only include the parts you actually need.

### Redirects

Redirects send visitors to a different URL. The address bar changes.

```json
{
  "redirects": [
    {
      "source": "/old-blog",
      "destination": "/blog"
    },
    {
      "source": "/docs/:path*",
      "destination": "/help/:path*"
    },
    {
      "source": "/sale",
      "destination": "/summer-sale",
      "statusCode": 302
    },
    {
      "source": "/chat",
      "destination": "https://discord.gg/your-invite"
    }
  ]
}
```

* `source` — the path to match. It must start with `/`.
* `destination` — where to send the visitor. Use an internal path (`/blog`) or a full external URL (`https://...`).
* By default a redirect is **permanent (301)**. For a temporary one, add `"statusCode": 302` (`307` and `308` work too).

### Rewrites

A rewrite serves a different file while keeping the visitor's URL the same. This is handy for single-page apps:

```json
{
  "rewrites": [
    {
      "source": "/app/:path*",
      "destination": "/index.html"
    }
  ]
}
```

Now any URL under `/app/...` shows your `index.html`, and your client-side router takes over from there.

### Custom headers

Add response headers to specific paths — for caching or security, for example:

```json
{
  "headers": [
    {
      "source": "/assets/:path*",
      "headers": [
        {
          "key": "Cache-Control",
          "value": "public, max-age=86400"
        }
      ]
    }
  ]
}
```

### Trailing slashes

Control whether your URLs end with a `/`:

```json
{
  "trailingSlash": true
}
```

* `true` — `/about` redirects to `/about/`
* `false` — `/about/` redirects to `/about`
* Leave it out to keep URLs exactly as visitors type them.

{% hint style="warning" %}
If you set `"trailingSlash": true`, write your redirect `source` paths **with** the trailing slash (for example `"/old-page/"`). The slash is added first, so a `source` without it won't match. When in doubt, leave `trailingSlash` out unless you really need it.
{% endhint %}

### Lowercase URLs

Redirect visitor-facing paths to lowercase:

```json
{
  "lowercaseUrls": true
}
```

With this enabled, `/BtC` redirects to `/btc`.&#x20;

Query strings and static files with extensions are preserved.

{% hint style="warning" %}
When lowercase URLs are enabled, write your redirect, rewrite, and header `source` paths in lowercase. URL normalization happens before those rules run.
{% endhint %}

### Matching patterns

Two tokens are available in `source` and `destination`:

* `:name` — matches one path segment. `/users/:id` matches `/users/42`, but not `/users/42/posts`.
* `:path*` — matches the rest of the path. `/docs/:path*` matches `/docs/a/b/c`.

You can reuse a captured value in the destination, like `"/help/:path*"`.

{% hint style="info" %}
Full regular expressions aren't supported — only `:name` and `:path*`. This keeps your site fast and secure.
{% endhint %}

### Full example

Here's a complete file that uses every feature together:

```json
{
  "version": 1,
  "lowercaseUrls": true,
  "trailingSlash": false,
  "redirects": [
    {
      "source": "/old-blog",
      "destination": "/blog"
    },
    {
      "source": "/docs/:path*",
      "destination": "/help/:path*"
    },
    {
      "source": "/u/:id",
      "destination": "/users/:id"
    },
    {
      "source": "/sale",
      "destination": "/summer-sale",
      "statusCode": 302
    },
    {
      "source": "/chat",
      "destination": "https://discord.gg/your-invite"
    }
  ],
  "rewrites": [
    {
      "source": "/app/:path*",
      "destination": "/index.html"
    }
  ],
  "headers": [
    {
      "source": "/assets/:path*",
      "headers": [
        {
          "key": "Cache-Control",
          "value": "public, max-age=86400"
        }
      ]
    },
    {
      "source": "/:path*",
      "headers": [
        {
          "key": "X-Frame-Options",
          "value": "DENY"
        }
      ]
    }
  ]
}
```

### Good to know

* Rules are applied in this order: **trailing slash → redirects → rewrites → your files → headers**.
* Each section can hold up to **400 rules**, and the file must be under **256 KB**.
* If `hollacloud.json` isn't valid, your publish fails with a message telling you what to fix — your live site stays untouched.
* The file itself is never served to visitors (a request for `/hollacloud.json` returns 404).
