Configuration is done via a single YAML file and a server restart is required in order for any changes to take effect. Trying to start the server with an invalid config file will result in an error.
## Preconfigured page
If you don't want to spend time reading through all the available configuration options and just want something to get you going quickly you can use the following `glance.yml` and make changes as you see fit:
This will give you a page that looks like the following:
![](images/preconfigured-page-preview.png)
Configure the widgets, add more of them, add extra pages, etc. Make it your own!
## Server
Server configuration is done through a top level `server` property. Example:
```yaml
server:
port: 8080
assets-path: /home/user/glance-assets
```
### Properties
| Name | Type | Required | Default |
| ---- | ---- | -------- | ------- |
| host | string | no | |
| port | number | no | 8080 |
| assets-path | string | no | |
#### `host`
The address which the server will listen on. Setting it to `localhost` means that only the machine that the server is running on will be able to access the dashboard. By default it will listen on all interfaces.
#### `port`
A number between 1 and 65,535, so long as that port isn't already used by anything else.
#### `assets-path`
The path to a directory that will be served by the server under the `/assets/` path. This is handy for widgets like the Monitor where you have to specify an icon URL and you want to self host all the icons rather than pointing to an external source.
> [!IMPORTANT]
>
> When installing through docker the path will point to the files inside the container. Don't forget to mount your assets path to the same path inside the container.
> Example:
>
> If your assets are in:
> ```
> /home/user/glance-assets
> ```
>
> You should mount:
> ```
> /home/user/glance-assets:/app/assets
> ```
>
> And your config should contain:
> ```
> assets-path: /app/assets
> ```
##### Examples
Say you have a directory `glance-assets` with a file `gitea-icon.png` in it and you specify your assets path like:
Theming is done through a top level `theme` property. Values for the colors are in [HSL](https://giggster.com/guide/basics/hue-saturation-lightness/) (hue, saturation, lightness) format. You can use a color picker [like this one](https://hslpicker.com/) to convert colors from other formats to HSL. The values are separated by a space and `%` is not required for any of the numbers.
Whether the scheme is light or dark. This does not change the background color, it inverts the text colors so that they look appropriately on a light background.
#### `background-color`
Color of the page and widgets.
#### `primary-color`
Color used across the page, largely to indicate unvisited links.
#### `positive-color`
Used to indicate that something is positive, such as stock price being up, twitch channel being live or a monitored site being online. If not set, the value of `primary-color` will be used.
#### `negative-color`
Oppposite of `positive-color`.
#### `contrast-multiplier`
Used to increase or decrease the contrast (in other words visibility) of the text. A value of `1.3` means that the text will be 30% lighter/darker depending on the scheme. Use this if you think that some of the text on the page is too dark and hard to read. Example:
![difference between 1 and 1.3 contrast](images/contrast-multiplier-example.png)
#### `text-saturation-multiplier`
Used to increase or decrease the saturation of text, useful when using a custom background color with a high amount of saturation and needing the text to have a more neutral color. `0.5` means that the saturation will be 50% lower and `1.5` means that it'll be 50% higher.
Path to a custom CSS file, either external or one from within the server configured assets path. Example:
```yaml
theme:
custom-css-file: /assets/my-style.css
```
> [!TIP]
>
> Because Glance uses a lot of utility classes it might be difficult to target some elements. To make it easier to style specific widgets, each widget has a `widget-type-{name}` class, so for example if you wanted to make the links inside just the RSS widget bigger you could use the following selector:
![illustration of pages and columns](images/pages-and-columns-illustration.png)
Using pages and columns is how widgets are organized. Each page contains up to 3 columns and each column can have any number of widgets.
### Pages
Pages are defined through a top level `pages` property. The page defined first becomes the home page and all pages get automatically added to the navigation bar in the order that they were defined. Example:
The name of the page which gets shown in the navigation bar.
#### `slug`
The URL friendly version of the title which is used to access the page. For example if the title of the page is "RSS Feeds" you can make the page accessible via `localhost:8080/feeds` by setting the slug to `feeds`. If not defined, it will automatically be generated from the title.
Whether to show a header displaying the name of the page on mobile. The header purposefully has a lot of vertical whitespace in order to push the content down and make it easier to reach on tall devices.
Columns are defined for each page using a `columns` property. There are two types of columns - `full` and `small`, which refers to their width. A small column takes up a fixed amount of width (300px) and a full column takes up the all of the remaining width. You can have up to 3 columns per page and you must have either 1 or 2 full columns. Example:
```yaml
pages:
- name: Home
columns:
- size: small
widgets: ...
- size: full
widgets: ...
- size: small
widgets: ...
```
### Properties
| Name | Type | Required |
| ---- | ---- | -------- |
| size | string | yes |
| widgets | array | no |
Here are some of the possible column configurations:
Used to change the appearance of the widget. Possible values are `vertical-list` and `horizontal-cards` where the former is intended to be used within a small column and the latter a full column. Below are previews of each style.
`vertical-list`
![preview of vertical-list style for RSS widget](images/rss-feed-vertical-list-preview.png)
Used to modify the height of the thumbnails. Works only when the style is set to `horizontal-cards`. The default value is `10` and the units are `rem`, if you want to for example double the height of the thumbnails you can set it to `20`.
If an RSS feed isn't returning item links with a base domain and Glance has failed to automatically detect the correct domain you can manually add a prefix to each link with this property.
Used to specify the order in which the posts should get returned. Possible values are `top`, `new`, and `best`.
##### `extra-sort-by`
Can be used to specify an additional sort which will be applied on top of the already sorted posts. By default does not apply any extra sorting and the only available option is `engagement`.
The `engagement` sort tries to place the posts with the most points and comments on top, also prioritizing recent over old posts.
> Reddit does not allow unauthorized API access from VPS IPs, if you're hosting Glance on a VPS you will get a 403 response. As a workaround you can route the traffic from Glance through a VPN or your own HTTP proxy using the `request-url-template` property.
Used to change the appearance of the widget. Possible values are `vertical-list`, `horizontal-cards` and `vertical-cards`. The first two were designed for full columns and the last for small columns.
How many posts are visible before the "SHOW MORE" button appears. Set to `-1` to never collapse. Not available when using the `vertical-cards` and `horizontal-cards` styles.
A custom request url that will be used to fetch the data instead. This is useful when you're hosting Glance on a VPS and Reddit is blocking the requests, and you want to route it through an HTTP proxy.
Placeholders:
`{REQUEST-URL}` - will be templated and replaced with the expanded request URL (i.e. https://www.reddit.com/r/selfhosted/hot.json). Example:
Available only when `sort-by` is set to `top`. Possible values are `hour`, `day`, `week`, `month`, `year` and `all`.
##### `search`
Keywords to search for. Searching within specific fields is also possible, **though keep in mind that Reddit may remove the ability to use any of these at any time**:
![](images/reddit-field-search.png)
##### `extra-sort-by`
Can be used to specify an additional sort which will be applied on top of the already sorted posts. By default does not apply any extra sorting and the only available option is `engagement`.
The `engagement` sort tries to place the posts with the most points and comments on top, also prioritizing recent over old posts.
> You can use the property `new-tab` with a value of `true` if you want to show search results in a new tab by default. <kbd>Ctrl</kbd> + <kbd>Enter</kbd> will then show results in the same tab.
What now? [Bangs](https://duckduckgo.com/bangs). They're shortcuts that allow you to use the same search box for many different sites. Assuming you have it configured, if for example you start your search input with `!yt` you'd be able to perform a search on YouTube:
![](images/search-widget-bangs-preview.png)
##### Properties for each bang
| Name | Type | Required |
| ---- | ---- | -------- |
| title | string | no |
| shortcut | string | yes |
| url | string | yes |
###### `title`
Optional title that will appear on the right side of the search bar when the query starts with the associated shortcut.
###### `shortcut`
Any value you wish to use as the shortcut for the search engine. It does not have to start with `!`.
> [!IMPORTANT]
>
> In YAML some characters have special meaning when placed in the beginning of a value. If your shortcut starts with `!` (and potentially some other special characters) you'll have to wrap the value in quotes:
> ```yaml
> shortcut: "!yt"
>```
###### `url`
The URL of the search engine. Use `{QUERY}` to indicate where the query value gets placed. Examples:
Display a widget provided by an external source (3rd party). If you want to learn more about developing extensions, checkout the [extensions documentation](extensions.md) (WIP).
```yaml
- type: extension
url: https://domain.com/widget/display-a-message
allow-potentially-dangerous-html: true
parameters:
message: Hello, world!
```
#### Properties
| Name | Type | Required | Default |
| ---- | ---- | -------- | ------- |
| url | string | yes | |
| allow-potentially-dangerous-html | boolean | no | false |
| parameters | key & value | no | |
##### `url`
The URL of the extension.
##### `allow-potentially-dangerous-html`
Whether to allow the extension to display HTML.
> [!WARNING]
>
> There's a reason this property is scary-sounding. It's intended to be used by developers who are comfortable with developing and using their own extensions. Do not enable it if you have no idea what it means or if you're not **absolutely sure** that the extension URL you're using is safe.
##### `parameters`
A list of keys and values that will be sent to the extension as query paramters.
Each bar represents a 2 hour interval. The yellow background represents sunrise and sunset. The blue dots represent the times of the day where there is a high chance for precipitation. You can hover over the bars to view the exact temperature for that time.
The name of the city and country to fetch weather information for. Attempting to launch the applcation with an invalid location will result in an error. You can use the [gecoding API page](https://open-meteo.com/en/docs/geocoding-api) to search for your specific location. Glance will use the first result from the list if there are multiple.
Display a list of sites and whether they are reachable (online) or not. This is determined by sending a GET request to the specified URL, if the response is 200 then the site is OK. The time it took to receive a response is also shown in milliseconds.
The URL which will be requested and its response will determine the status of the site. Optionally, you can specify this using an environment variable with the syntax `${VARIABLE_NAME}`.
Optional URL to an image which will be used as the icon for the site. Can be an external URL or internal via [server configured assets](#assets-path). You can also directly use [Simple Icons](https://simpleicons.org/) via a `si:` prefix:
```yaml
icon: si:jellyfin
icon: si:gitea
icon: si:adguard
```
> [!WARNING]
>
> Simple Icons are loaded externally and are hosted on `cdnjs.cloudflare.com`, if you do not wish to depend on a 3rd party you are free to download the icons individually and host them locally.
Display a list of releases for specific repositories on Github. Draft releases and prereleases will not be shown.
Example:
```yaml
- type: releases
repositories:
- immich-app/immich
- go-gitea/gitea
- dani-garcia/vaultwarden
- jellyfin/jellyfin
```
Preview:
![](images/releases-widget-preview.png)
#### Properties
| Name | Type | Required | Default |
| ---- | ---- | -------- | ------- |
| repositories | array | yes | |
| token | string | no | |
| limit | integer | no | 10 |
| collapse-after | integer | no | 5 |
##### `repositories`
A list of repositores for which to fetch the latest release for. Only the name/repo is required, not the full URL.
##### `token`
Without authentication Github allows for up to 60 requests per hour. You can easily exceed this limit and start seeing errors if you're tracking lots of repositories or your cache time is low. To circumvent this you can [create a read only token from your Github account](https://github.com/settings/personal-access-tokens/new) and provide it here.
You can also specify the value for this token through an ENV variable using the syntax `${GITHUB_TOKEN}` where `GITHUB_TOKEN` is the name of the variable that holds the token. If you've installed Glance through docker you can specify the token in your docker-compose:
```yaml
services:
glance:
image: glanceapp/glance
environment:
- GITHUB_TOKEN: <yourtoken>
```
and then use it in your `glance.yml` like this:
```yaml
- type: releases
token: ${GITHUB_TOKEN}
repositories: ...
```
This way you can safely check your `glance.yml` in version control without exposing the token.
##### `limit`
The maximum number of releases to show.
#### `collapse-after`
How many releases are visible before the "SHOW MORE" button appears. Set to `-1` to never collapse.
The owner and repository name that will have their information displayed.
##### `token`
Without authentication Github allows for up to 60 requests per hour. You can easily exceed this limit and start seeing errors if your cache time is low or you have many instances of this widget. To circumvent this you can [create a read only token from your Github account](https://github.com/settings/personal-access-tokens/new) and provide it here.
##### `pull-requests-limit`
The maximum number of latest open pull requests to show. Set to `-1` to not show any.
##### `issues-limit`
The maximum number of latest open issues to show. Set to `-1` to not show any.
URL pointing to an image. You can also directly use [Simple Icons](https://simpleicons.org/) via a `si:` prefix:
```yaml
icon: si:gmail
icon: si:youtube
icon: si:reddit
```
> [!WARNING]
>
> Simple Icons are loaded externally and are hosted on `cdnjs.cloudflare.com`, if you do not wish to depend on a 3rd party you are free to download the icons individually and host them locally.
`same-tab`
Whether to open the link in the same tab or a new one.
| instance-url | string | no | `https://www.changedetection.io` |
| token | string | no | |
| limit | integer | no | 10 |
| collapse-after | integer | no | 5 |
| watches | array of strings | no | |
##### `instance-url`
The URL pointing to your instance of `changedetection.io`.
##### `token`
The API access token which can be found in `SETTINGS > API`. Optionally, you can specify this using an environment variable with the syntax `${VARIABLE_NAME}`.
##### `limit`
The maximum number of watches to show.
##### `collapse-after`
How many watches are visible before the "SHOW MORE" button appears. Set to `-1` to never collapse.
##### `watches`
By default all of the configured watches will be shown. Optionally, you can specify a list of UUIDs for the specific watches you want to have listed:
Whether to show the time in 12 or 24 hour format. Possible values are `12h` and `24h`.
#### Properties for each timezone
| Name | Type | Required | Default |
| ---- | ---- | -------- | ------- |
| timezone | string | yes | |
| label | string | no | |
##### `timezone`
A timezone identifier such as `Europe/London`, `America/New_York`, etc. The full list of available identifiers can be found [here](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones).
##### `label`
Optionally, override the display value for the timezone to something more meaningful such as "Home", "Work" or anything else.
By default the markets are displayed in the order they were defined. You can customize their ordering by setting the `sort-by` property to `absolute-change` for descending order based on the stock's absolute price change.