## 1. Project Overview & Quickstart (umami-software/umami)

## File: README.md

<h1 align="center">Umami</h1>





---

## 🚀 Getting Started

A detailed getting started guide can be found at [umami.is/docs](https://umami.is/docs/).

---

## 🛠 Installing from Source

### Requirements

- A server with Node.js version 18.18+.
- A PostgreSQL database version v12.14+.

### Get the source code and install packages

```bash
git clone https://github.com/umami-software/umami.git
cd umami
pnpm install
```

### Configure Umami

Create an `.env` file with the following:

```bash
DATABASE_URL=connection-url
```

Optional: set `API_URL` to change the base URL used by internal UI API calls.
Relative paths are served under `BASE_PATH`; absolute URLs are proxied through the local `/api` route.
For example, `API_URL=/internal-api` or `API_URL=https://api.example.com/api`.

Optional: set `TWO_FACTOR_ENCRYPTION_KEY` to a 64-character hex string to enable two-factor
authentication. Generate one with `openssl rand -hex 32`. Two-factor authentication is unavailable
and cannot be required until this key is set.

The connection URL format:

```bash
postgresql://username:mypassword@localhost:5432/mydb
```

### Build the Application

```bash
pnpm run build
```

The build step will create tables in your database if you are installing for the first time. It will also create a login user with username **admin** and password **umami**.

### Start the Application

```bash
pnpm run start
```

By default, this will launch the application on `http://localhost:3000`. You will need to either [proxy](https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/) requests from your web server or change the [port](https://nextjs.org/docs/api-reference/cli#production) to serve the application directly.

---

## 🐳 Installing with Docker

Umami provides Docker images as well as a Docker compose file for easy deployment.

Docker image:

```bash
docker pull docker.umami.is/umami-software/umami:latest
```

Docker compose (Runs Umami with a PostgreSQL database):

```bash
docker compose up -d
```

---

## 🔄 Getting Updates

To get the latest features, simply do a pull, install any new dependencies, and rebuild:

```bash
git pull
pnpm install
pnpm build
```

To update the Docker image, simply pull the new images and rebuild:

```bash
docker compose pull
docker compose up --force-recreate -d
```

---

## 🛟 Support



[release-shield]: https://img.shields.io/github/release/umami-software/umami.svg
[releases-url]: https://github.com/umami-software/umami/releases
[license-shield]: https://img.shields.io/github/license/umami-software/umami.svg
[license-url]: https://github.com/umami-software/umami/blob/master/LICENSE
[build-shield]: https://img.shields.io/github/actions/workflow/status/umami-software/umami/ci.yml
[build-url]: https://github.com/umami-software/umami/actions
[github-shield]: https://img.shields.io/badge/GitHub--blue?style=social&logo=github
[github-url]: https://github.com/umami-software/umami
[twitter-shield]: https://img.shields.io/badge/Twitter--blue?style=social&logo=twitter
[twitter-url]: https://twitter.com/umami_software
[linkedin-shield]: https://img.shields.io/badge/LinkedIn--blue?style=social&logo=linkedin
[linkedin-url]: https://linkedin.com/company/umami-software
[discord-shield]: https://img.shields.io/badge/Discord--blue?style=social&logo=discord
[discord-url]: https://discord.com/invite/4dz4zcXYrQ

---

## File: podman/README.md

# How to deploy umami on podman


## How to use

1. Rename `env.sample` to `.env`
2. Edit `.env` file. At the minimum set the passwords.
3. Start umami by running `podman-compose up -d`.

If you need to stop umami, you can do so by running `podman-compose down`.


### Install systemd service (optional)

If you want to install a systemd service to run umami, you can use the provided
systemd service.

Edit `umami.service` and change these two variables:


	WorkingDirectory=/opt/apps/umami
	EnvironmentFile=/opt/apps/umami/.env

`WorkingDirectory` should be changed to the path in which `podman-compose.yml`
is located.

`EnvironmentFile` should be changed to the path in which your `.env`file is
located.

You can run the script `install-systemd-user-service` to install the systemd
service under the current user.


	./install-systemd-user-service

Note: this script will enable the service and also start it. So it will assume
that umami is not currently running.  If you started it previously, bring it
down using:

	podman-compose down



## Compatibility

These files should be compatible with podman 4.3+.

I have tested this on Debian GNU/Linux 12 (bookworm) and with the podman that
is distributed with the official Debian stable mirrors (podman
v4.3.1+ds1-8+deb12u1, podman-compose v1.0.3-3).

## 2. Official Technical Reference & Guides (umami-software/docs)

## File: README.md

# umami-docs

This is a Next.js application generated with
[Create Fumadocs](https://github.com/fuma-nama/fumadocs).

Run development server:

```bash
npm run dev
# or
pnpm dev
# or
yarn dev
```

Open http://localhost:3000 with your browser to see the result.

## Explore

In the project, you can see:

- `lib/source.ts`: Code for content source adapter, [`loader()`](https://fumadocs.dev/docs/headless/source-api) provides the interface to access your content.
- `lib/layout.shared.tsx`: Shared options for layouts, optional but preferred to keep.

| Route                     | Description                                            |
| ------------------------- | ------------------------------------------------------ |
| `app/(home)`              | The route group for your landing page and other pages. |
| `app/docs`                | The documentation layout and pages.                    |
| `app/api/search/route.ts` | The Route Handler for search.                          |

### Fumadocs MDX

A `source.config.ts` config file has been included, you can customise different options like frontmatter schema.

Read the [Introduction](https://fumadocs.dev/docs/mdx) for further details.

## Learn More

To learn more about Next.js and Fumadocs, take a look at the following
resources:

- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js
  features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
- [Fumadocs](https://fumadocs.dev) - learn about Fumadocs

---

## File: content/docs/(quickstart)/add-a-website.mdx

---
title: Add a website
---

Log into Umami and click on **Websites** in the sidebar.



Click on the **Add website** button in the top-right corner.



Fill out the form details and click the **Save** button.



The **Name** field can be whatever you want. Usually it's the same as the domain name.

The **Domain** field is the actual domain of your website. It is used to filter out your own website
from the list of referrers in your metrics.

---

## File: content/docs/(quickstart)/collect-data.mdx

---
title: Collect data
---

To start collecting data, you need to install the tracker script to your website.

To get your tracking code, click on the **Edit** button for the website you want to track.



The tracking code can be found under the **Tracking code** section.

Copy the code and insert it into the `<head>` section of your website.



Then visit your website and data should immediately appear in your Umami dashboard.

### Troubleshooting

- **Data not appearing?** Open your browser developer tools (F12) and check the Network tab for requests to your Umami instance. Make sure the script is loading without errors.
- **Ad blockers** may prevent the tracking script from loading. See [Bypass ad blockers](/docs/bypass-ad-blockers) for solutions.
- **Next.js** - Insert the tracking code using the [next/script](https://nextjs.org/docs/app/api-reference/components/script) component instead of a plain `<script>` tag.
- **Single page applications** - Umami automatically tracks page navigations in SPAs. No additional configuration is needed.

---

## File: content/docs/(quickstart)/enable-share-url.mdx

---
title: Enable Share URL
---

*Available since v1.0.0*

Share URLs make it easy to share your analytics.

By default your website’s metrics are private. When you want to share insights, you can generate a public **Share URL** for specific views.

## What You Can Share

When you create a Share URL, you can choose exactly which views are visible. This gives you full control over what data is shared publicly.

### Traffic

High-level metrics and real-time views that show who and how visitors navigate your site.

- Overview
- Events
- Sessions
- Realtime
- Compare
- Breakdown

### Behavior

Insights into how users interact with your site and move through key actions.

- Goals
- Funnels
- Journeys
- Retention

### Growth

Metrics focused on campaigns, revenue, and attribution performance.

- UTM
- Revenue
- Attribution

## Add a Share URL

Log into Umami and click on **Websites** in the sidebar.



Click on the **Edit** button for the website you want to edit.



Navigate to the **Share URL** section and click on the **Add** button. 



Fill out the form details and click the **Save** button.



The application will auto-generate a **Share URL**. Click on the link to access your share page.

---

## File: content/docs/(quickstart)/login.mdx

---
title: Login
---

Your Umami installation will create a default administrator account with the username **admin** and the password **umami**.

The first thing you will want to do is log in and change your password.



Once logged in, click on the side nav profile button then click **Settings**.



Then navigate to **Profile** and click the **Change password** button.



You can also enable [two-factor authentication](/docs/two-factor-authentication) from the **Security** tab for
extra account protection.

---

## File: content/docs/(how-to)/bypass-ad-blockers.mdx

---
title: Bypass ad blockers
---

Even though Umami is a privacy-focused product, it may still get blocked by
certain ad blockers. Ad blockers use blocklists maintained by many different people.
Some lists can be overly aggressive, for example blocking anything with even
the word `analytics` in it or simply blocking all tracking products regardless
of how they operate.

Here are few methods you can use to avoid ad blockers.

## Proxying

Proxying is done at the server level so you will need access to your web server to make changes.
With this method, you can proxy the tracking script itself to hide the actual name and location of
the original script.

For example, you can have a script on your website that is:

`https://your-website.com/script.js`

That is proxying the file at:

`https://cloud.umami.is/script.js`

So even if the ad blocker blocks the `cloud.umami.is` domain, your own domain would be safe.

Here are some tutorials you can use:

- [Nginx](https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/)
- [Apache](https://httpd.apache.org/docs/2.4/howto/reverse_proxy.html)

To implement this using server-side, what you can do is make a separate endpoint.
For instance, in [Express.js](https://expressjs.com):

```js
app.get("/stats.js", async (req, res) => {
    const scriptText = await fetch("https://cloud.umami.is/script.js");
    res.send(await scriptText.text())
});
```

Then in your html head tag:
```html
<script defer src="/stats.js" data-website-id="..."></script>
```


If you are using a framework like [Next.js](https://nextjs.org), you can use their [rewrites](https://nextjs.org/docs/pages/api-reference/next-config-js/rewrites) feature.

## Hosting the tracker script

If you don't have access to the web server and are unable to proxy the script, you can simply host the entire
tracker script on your own domain.

1. Open the script URL in your browser, `https://cloud.umami.is/script.js`.
2. Save the file.
3. Upload the file to your domain.
4. Set the `data-host-url` attribute to send data to the correct location. See [tracker configuration](https://umami.is/docs/tracker-configuration).

Note that this method is not as reliable as proxying and if the tracker script were to change, you would need
to download and update the script again.

## Using environment variables (self-hosting)

If you are self-hosting Umami, you can configure your instance using [environment variables](/docs/environment-variables).

There are two sources that could potentially be blocked:

1. The tracker script at `https://your-umami.com/script.js`
2. The stats collection endpoint at `https://your-umami.com/api/send`.

The [`TRACKER_SCRIPT_NAME`](/docs/environment-variables#tracker_script_name) variable can be used to rename your tracker script to
something like `x.js`. You would then change your script source to `https://your-umami.com/x.js`.

The [`COLLECT_API_ENDPOINT`](/docs/environment-variables#collect_api_endpoint) variable can be used to rename your endpoint to something
like `/api/x`. The tracker script will automatically make calls to your custom endpoint name
instead of `/api/send`.

---

## File: content/docs/(how-to)/exclude-my-own-visits.mdx

---
title: Exclude my own visits
---

You want to visit your own website, but you don't want your visits to appear in
your stats. To accomplish this, you need to add a setting to your browser.

Bring up the developer console in your browser: `Settings -> More tools -> Developer tools`

In the console, enter the following code and hit `Enter`:

```javascript
localStorage.setItem('umami.disabled', 1);
```

This setting applies **per website**, so you will need to do this for each website
you want to be excluded from.

To remove the setting, enter the following code and hit `Enter`:

```javascript
localStorage.removeItem('umami.disabled');
```

---

## File: content/docs/(how-to)/track-outbound-links.mdx

---
title: Track outbound links
---

When a user clicks on a link to an external site, this event is normally not captured because
the user is leaving the site where Umami runs. However, using [events](/docs/track-events) you can
track this behavior.

To track outbound links, you need to add data attributes to the anchor tag containing the external link.
When the tag is clicked, the event will be triggered. In this example, we are sending
an event named `outbound-link-click` with the value of `url` set to the external URL.

```html
<a href="https://www.external-website.com"
  data-umami-event="outbound-link-click"
  data-umami-event-url="https://www.external-website.com"
>
  External link
</a>
```

If you don't want to manually update all your anchor tags, you can use this script to automatically add the
event attributes to all your outbound tags. You can place the following script at the bottom of your HTML body.

```html
<script type="text/javascript">
  (() => {
    const name = 'outbound-link-click';
    document.querySelectorAll('a').forEach(a => {
      if (a.host !== window.location.host && !a.getAttribute('data-umami-event')) {
        a.setAttribute('data-umami-event', name);
        a.setAttribute('data-umami-event-url', a.href);
      }
    });
  })();
</script>
```

---

## File: content/docs/(filtering)/cohorts.mdx

---
title: Cohorts
---

*Available since v3.0.0*

Cohorts let you group users based on specific actions, like visiting a URL or triggering an event, within a selected date
range. This makes it easy to track and compare behavior patterns over time for different user groups,
helping you uncover trends and measure engagement more effectively.

## Add a cohort

Click on **Cohorts** from the side nav then click on the **Add cohort** button.



Choose your filters and click **Save**.



- Cohorts allow you to filter on date range and if a user visited a specific URL or triggered a specific event.
- To have a static cohort choose a **Custom Range** from the date picker so the users remain static.

## Applying a cohort

Add a filter and switch to the **Cohorts** tab. Click on a cohort and click on the **Apply** button.



## Edit or Delete a cohort

From the **Cohorts** screen click on the **Edit** button to update a cohort or click on the **Delete** button to delete a cohort.

---

## File: content/docs/(filtering)/filters.mdx

---
title: Filters
---

*Available since v2.6.0 · Enhanced in v3.0.0, v3.3.0*

Umami has built-in reporting to help you gain deeper insights into parts of your data. With universal filtering, you can apply conditions across all screens/reports for consistent analysis.
Segments let you group users based on shared attributes or behaviors. Cohorts take this further by analyzing groups of
users over time, helping you track retention, performance, and long-term trends.

## Available filters

Filters are grouped by category in the filter panel.

| Category | Filter | Description |
| --- | --- | --- |
| URL | Path | URL path of the visited page. |
| URL | Query | The query string portion of the URL (e.g., `?ref=homepage`). |
| URL | Page Title | The HTML title of the page as seen in the browser tab. |
| Sources | Referrer | The source that directed the visitor to your site. |
| Location | Country | The visitor’s country based on geolocation. |
| Location | Region | The visitor’s state, province, or region. |
| Location | City | The visitor’s city location. |
| Environment | Browser | The web browser used by the visitor (e.g., Chrome, Safari, Firefox). |
| Environment | OS | The operating system of the visitor’s device (e.g., Windows, macOS, iOS, Android). |
| Environment | Device | The type of device used, such as desktop, tablet, or mobile. |
| UTM | UTM Source | The traffic source (e.g., `google`, `newsletter`). |
| UTM | UTM Medium | The marketing medium (e.g., `cpc`, `email`). |
| UTM | UTM Campaign | The campaign name. |
| UTM | UTM Content | The specific ad or link content. |
| UTM | UTM Term | The paid search keyword. |
| Other | Hostname | The domain where the page was accessed. |
| Other | Distinct ID | A custom identifier you assign to a visitor. See [Distinct IDs](/docs/distinct-ids). |
| Other | Tag | A label or keyword you assign to your data. See [Tags](/docs/tags). |
| Other | Event | Custom events triggered by users (e.g., button clicks, form submissions, video plays). |

## Property filters

In addition to the standard fields above, the filter panel has dedicated tabs for filtering on custom data:

- **Session data** — filter by any [session data](/docs/tracker-functions#session-data) property you've saved (e.g. `plan`, `company`). Available on every report page.
- **Event properties** — filter by any custom event property. Only available on the **Events** page, since these filters are scoped to a specific event.



Each property filter is type-aware: the available operators (equals, contains, before/after, etc.) depend on
whether the property was saved as a string, number, boolean, date, or array.

## Match mode

When applying multiple filters, use the **Match** toggle to control how conditions are combined:

| Mode | Description |
| --- | --- |
| All | The visitor must match every condition (logical AND). |
| Any | The visitor must match at least one condition (logical OR). |

## Filter operators

Each filter condition supports the following operators:

| Operator | Description |
| --- | --- |
| Is | Exact match. |
| Is not | Excludes an exact match. |
| Contains | Value includes the specified string. |
| Does not contain | Value does not include the specified string. |
| Matches regex | Value matches the provided regular expression. |
| Does not match regex | Value does not match the provided regular expression. |

## Universal filtering

The date range and filters from the website page can now be applied to all screens and reports.





## Accessing filters

Log into Umami and click on **Websites** in the sidebar.



Click on **View** for the website you want to view.



The top of the screen will have date and field filters that can be applied across all screens.



## Add a filter

**Method 1:** Click the **Filter** button to apply filters



**Method 2:** Click on any row on the metrics cards in the overview screen.



The current filters applied to each page can be seen at the top of the page.