# Source: https://juno.build/docs/reference/configuration.md

# Source: https://juno.build/docs/build/hosting/configuration.md

# Configuration

You can customize your hosting environment to fit your needs, including:

*   Specify which `source` files in your local project directory you want to deploy? ([Learn how.](#source))
*   Ignore some files during deployment. ([Learn how.](#ignore-files))
*   Configure HTTP `headers` to pass along additional information about a request or a response. ([Learn how.](#http-headers))
*   Serve a customized 404 page. ([Learn how.](#customize-a-404not-found-page))
*   Set up `redirects` for pages that you've moved or deleted. ([Learn how.](#redirects))
*   Set up `rewrites`. ([Learn how.](#rewrites))
*   Customize file `compression` for optimal performance. ([Learn how.](#precompress))
*   Customize the `encoding` behavior of your files. ([Learn how.](#encoding-types))
*   Allow your project to be embedded as an `iframe`. ([Learn how.](#iframe))
*   Customize `assertions` to modify the default verification behavior of the CLI. ([Learn how.](#assertions))

---

## Where do you define your Hosting configuration?

Your hosting configuration is defined in the Juno [configuration](/docs/reference/configuration.md) file, which is automatically created when you run [juno config init](/docs/reference/cli.md#init) or [juno hosting deploy](/docs/reference/cli.md#deploy) for the first time.

---

## How do you apply your changes?

To apply any changes, execute the [juno config apply](/docs/reference/cli.md#apply) command with the CLI.

---

## Options

The list below outlines the available hosting options you can configure to tailor your hosting.

### Source

The `source` field specifies the directory that contains the built assets for your Satellite. This is typically the output directory generated by your build process after running a command like `npm run build`.

Commonly, or if you are using the templates, these are the folders that can be set as the `source` field:

| Framework | Source |
| --- | --- |
| Next.js | `out` |
| React, Astro, or Vue | `dist` |
| SvelteKit | `build` |
| Angular | `dist/<your-project-name>/browser` |

Juno uses this directory to locate the files that will be deployed as part of your Satellite. Ensure that this directory includes all the necessary assets, such as HTML, JavaScript, CSS, and any other static or dynamic resources your application requires.

juno.config.js

```
import { defineConfig } from "@junobuild/config";export default defineConfig({  satellite: {    ids: {      production: "qsgjb-riaaa-aaaaa-aaaga-cai"    },    source: "dist"  }});
```

### Ignore files

The `ignore` attribute allows you to exclude certain files from being deployed to your Satellite.

This attribute works similarly to Git's `.gitignore`, and you can specify which files to ignore using globs.

Here is an example of how the ignore attribute can be utilized:

juno.config.js

```
import { defineConfig } from "@junobuild/config";export default defineConfig({  satellite: {    ids: {      production: "qsgjb-riaaa-aaaaa-aaaga-cai"    },    source: "dist",    ignore: ["**/*.txt", ".tmp/"]  }});
```

### HTTP Headers

Headers allow the client and the Satellite to pass additional information along with a request or a response. Some sets of headers can affect how the browser handles the page and its content.

For instance, you may want to set a specific `Cache-Control` for performance reasons.

Here's an example of the `headers` object:

juno.config.js

```
import { defineConfig } from "@junobuild/config";export default defineConfig({  satellite: {    ids: {      production: "qsgjb-riaaa-aaaaa-aaaga-cai"    },    source: "dist",    storage: {      headers: [        {          source: "/",          headers: [["Cache-Control", "public,max-age=0,must-revalidate"]]        },        {          source: "assets/fonts/*",          headers: [["Cache-Control", "max-age=31536000"]]        },        {          source: "**/*.jpg",          headers: [            ["Cache-Control", "max-age=31536000"],            ["Access-Control-Allow-Origin", "*"]          ]        }      ]    }  }});
```

This `source` attribute works similarly to Git's `.gitignore`, and you can specify which files match the headers using globs.

The `headers` is an array of objects, each containing `key` and `value`, and these apply to the matching paths.

**Note:**

*   The `Content-Type` header is calculated automatically and cannot be altered.
*   No validation or check for uniqueness is performed. For example, if a header matches a file based on multiple rules, multiple headers will be set.
*   Likewise, if you provide the same header when you [upload](https://juno.build/docs/build/storage#upload-file) file to your "Storage" and within the configuration, both headers will be set in the response.

### Customize a 404/Not Found page

By default, all unknown paths are automatically rewritten to `/index.html`. However, if you wish to serve a custom `404 Not Found` error when a user attempts to access a non-existent page, you can do so without requiring additional configuration.

Simply upload a custom `404.html` file to your Satellite that should be served from the root path of your site.

### Redirects

Use a URL redirect to prevent broken links if you've moved a page or to shorten URLs. For example, you could redirect a browser from `juno.build/start-building` to `juno.build/get-started.html`.

Here's the basic structure for a `redirects` attribute.

juno.config.js

```
import { defineConfig } from "@junobuild/config";export default defineConfig({  satellite: {    ids: {      production: "qsgjb-riaaa-aaaaa-aaaga-cai"    },    source: "dist",    storage: {      redirects: [        {          source: "/hello",          location: "/world/index.html",          code: 301        }      ]    }  }});
```

The `redirects` attribute contains an array of redirect rules:

| Field | Description |
| --- | --- |
| **source** | This `source` attribute works similarly to Git's `.gitignore`, and you can specify which files match the redirects using globs. |
| **location** | A relative path to where the browser should make a new request. |
| **code** | The HTTPS response code. Use a type of `301` for 'Moved Permanently' or `302` for 'Found' (Temporary Redirect). |

### Rewrites

You can utilize optional rewrites to display the same content for multiple URLs. Rewrites are especially useful when combined with pattern matching, allowing acceptance of any URL that matches the pattern.

Here's the basic structure for a `rewrites` attribute.

juno.config.js

```
import { defineConfig } from "@junobuild/config";export default defineConfig({  satellite: {    ids: {      production: "qsgjb-riaaa-aaaaa-aaaga-cai"    },    source: "dist",    storage: {      rewrites: [        {          source: "/hello/**",          destination: "/hello/world.html"        }      ]    }  }});
```

This `source` attribute works similarly to Git's `.gitignore`, and you can specify which files match the rewrites using globs.

**Note:**

*   Rewrites are only applied to requests that do not match any existing resources.
*   By default, all unknown paths are automatically rewritten to `/index.html` (or `/404.html` if you provide such a page). You cannot disable this default behavior.

### GZIP

When deploying your application, the CLI automatically searches for files matching the pattern `**/*.+(css|js|mjs|html)` in the `source` folder to optimize them using Gzip compression. This improves the performance of your app when it is served on the web.

By default, precompression stores **both** the original and compressed versions in Storage.

You can disable it entirely or customize which files are precompressed, whether to keep originals, and which compression algorithm to use.

**Note:**

If you change the precompress configuration and your project has already been deployed, run `juno hosting clear` before redeploying to ensure you change is applied.

#### Disable precompression

Set the `precompress` option to `false` in your configuration:

juno.config.js

```
import { defineConfig } from "@junobuild/config";export default defineConfig({  satellite: {    ids: {      production: "qsgjb-riaaa-aaaaa-aaaga-cai"    },    source: "dist",    precompress: false  }});
```

#### Customize the file matching pattern

If you want to customize the default pattern `**/*.+(css|js|mjs|html)` to better suit your needs, you can specify your own pattern. For example:

juno.config.js

```
import { defineConfig } from "@junobuild/config";export default defineConfig({  satellite: {    ids: {      production: "qsgjb-riaaa-aaaaa-aaaga-cai"    },    source: "dist",    precompress: {      pattern: "**/*.jpg" // precompress JPEG files only    }  }});
```

#### Decide what happens to original files

The `mode` option controls what happens to the original files after compression:

*   `"both"` â upload both the original and the compressed version. _(default)_
*   `"replace"` â upload only the compressed version and serve it with the appropriate `Content-Encoding` header.

**Warning:**

If you use `replace` for HTML, some social media crawlers (e.g. Twitter, LinkedIn) may not be able to fetch your pages correctly, resulting in missing or broken social previews.

To avoid this, instead of providing a single precompression rule, it's recommended to fine-tune the behavior using an **array of rules** (([see below](#use-multiple-rules))).

juno.config.js

```
import { defineConfig } from "@junobuild/config";export default defineConfig({  satellite: {    ids: {      production: "qsgjb-riaaa-aaaaa-aaaga-cai"    },    source: "dist",    precompress: {      mode: "replace"    }  }});
```

#### Choose the compression algorithm

By default, precompression uses **Gzip** (`algorithm: "gzip"`) because it offers a good balance between compression speed, compatibility, and size.

You can switch to **Brotli** (`algorithm: "brotli"`) for potentially smaller files, especially for text-based assets such as those compressed by default like HTML, CSS, and JavaScript.

juno.config.js

```
import { defineConfig } from "@junobuild/config";export default defineConfig({  satellite: {    ids: {      production: "qsgjb-riaaa-aaaaa-aaaga-cai"    },    source: "dist",    precompress: {      algorithm: "brotli"    }  }});
```

#### Use multiple rules

**Tip:**

This strategy works great for modern static sites.

In some cases, particularly when using `mode: replace`, you may want to apply different precompression strategies depending on the file type. For example, using replace for JavaScript and CSS files, but doing so for HTML can break social media previews.

To handle this, the precompress option also accepts an array of rules:

juno.config.js

```
import { defineConfig } from "@junobuild/config";export default defineConfig({  satellite: {    ids: {      production: "qsgjb-riaaa-aaaaa-aaaga-cai"    },    source: "dist",    precompress: [      {        pattern: "**/*.+(js|mjs|css)",        algorithm: "brotli",        mode: "replace"      },      {        pattern: "**/*.html",        algorithm: "brotli",        mode: "both"      }    ]  }});
```

### Encoding types

When deploying, the CLI automatically maps the encoding type based on the file extension. The encoding information is then used in the Satellite to provide the appropriate HTTP response header `Content-Encoding`.

The default mappings are as follows:

*   `.Z` = `compress`
*   `.gz` = `gzip`
*   `.br` = `br`
*   `.zlib` = `deflate`
*   rest = `identity` (no compression)

You can also customize the encoding behavior by using the "encoding" attribute in the configuration file.

This attribute works similarly to Git's `.gitignore`, and you can specify which files to ignore using globs.

Here is an example of how the "encoding" attribute can be utilized:

juno.config.js

```
import { defineConfig } from "@junobuild/config";export default defineConfig({  satellite: {    ids: {      production: "qsgjb-riaaa-aaaaa-aaaga-cai"    },    source: "dist",    encoding: [["**/releases/*.gz", "identity"]]  }});
```

### iframe

For security reasons and to prevent click-jacking attacks, dapps deployed with Juno are, by default, set to deny embedding in other sites.

You can customize this behavior by setting the `iframe` option to either `same-origin`, which restricts your pages to be displayed only if all ancestor frames have the same origin as the page itself, or `allow-any`, which allows your project to be embeddable by any site.

juno.config.js

```
import { defineConfig } from "@junobuild/config";export default defineConfig({  satellite: {    ids: {      production: "qsgjb-riaaa-aaaaa-aaaga-cai"    },    source: "dist",    storage: {      iframe: "same-origin"    }  }});
```

### Assertions

The CLI conducts several assertions when interacting with your Satellite, one of which involves monitoring the heap memory size. Typically, the CLI checks to ensure that the heap memory does not exceed the 1 GB limit before deployment. For instance, if your heap memory usage is close to 900 MB, the CLI will prompt you to confirm the deployment.

You can customize this behavior by adjusting the heap memory limit in bytes. For example, to set a new limit of 678 MB, update your configuration as follows:

juno.config.js

```
import { defineConfig } from "@junobuild/config";export default defineConfig({  satellite: {    ids: {      production: "qsgjb-riaaa-aaaaa-aaaga-cai"    },    source: "dist",    assertions: {      heapMemory: 678000000    }  }});
```

Alternatively, these checks can be completely disabled. To do so, set the `heapMemory` assertion to `false`:

juno.config.js

```
import { defineConfig } from "@junobuild/config";export default defineConfig({  satellite: {    ids: {      production: "qsgjb-riaaa-aaaaa-aaaga-cai"    },    source: "dist",    assertions: {      heapMemory: false    }  }});
```