# the app's own icon (app.Icon)

> `app.Icon` names one of the SVG files your app ships as its icon. The app serves it at its own `/favicon.svg`, and every page's head links it, so browser tabs, bookmarks and home-screen icons show your mark instead of the platform's. PNG and ICO versions are rendered from the same SVG for Google Search and phone home screens. A page can carry its own icon with `head { Icon = … }`.

<!-- id: config-icon · area: config · stability: preview · html: https://osysharp.com/reference/config/icon/ -->

## Summary        {#summary}
Every page shows an icon in its browser tab. Until an app says otherwise, that is the platform's. One line makes it
the app's own:

```osy syntax
app.Icon = Art.Logo;      // art/logo.svg — one of the SVG files this app ships
```

## Signature      {#signature}
```osy syntax
app.Icon = Art.<Name>;           // the app's icon — any page without its own
head { Icon = Art.<Name>; }      // one page's own icon, on that page only
```

`Art` is the vocabulary of SVG files the app ships ([SVG assets](https://osysharp.com/reference/ui/svg-assets/)). The icon is named from it rather than written as
a path, so a missing file is a compile error that lists the names that exist. Anything other than an `Art.X` is
refused with the one-line fix.

## Description    {#description}

### Where it is served, and who reads it   {#where}
The icon is served at the app's own **`/favicon.svg`**, on the app's own host (its subdomain), and every page's head
links it. The address never changes between versions. A new icon is picked up by revalidation, not by a new URL.

Several things read an icon, and each reads it **from the origin the page is on**:

- a **browser tab** and the history list;
- a **bookmark**;
- a **home-screen icon**, when someone adds the app to a phone's home screen.

So every app on its own subdomain shows its own icon in all three.

**Google Search** follows its own rules, published in Google Search Central's favicon guidelines
(<https://developers.google.com/search/docs/appearance/favicon-in-search>, last updated 2026-08-28, read 2026-09-28):

- *"Google Search only supports one favicon per site, where a site is defined by the hostname."* The page lists a
  subdomain home page (`https://news.example.com`) as **supported**, and a subdirectory (`https://example.com/news`)
  as **not supported**. So an app on its own subdomain can have its own icon in Search. It does not inherit the root
  domain's.
- Google finds the icon through the `<link rel="icon">` on the **home page**. Googlebot must be able to crawl that page,
  and Googlebot-Image must be able to crawl the icon. An app's `/` page is therefore what decides its Search icon.
- The listed formats are *"BMP, GIF, ICO, PNG, JPEG, PPM, and TIFF"*, and the page recommends larger than 48×48 px.
  **SVG is not on that list**, so Search reads the raster versions the platform renders for you (below).

### The raster versions   {#raster}
The same SVG is **rendered** to the formats that cannot read an SVG, once per app version, all on the app's own host:

| address | size | read by |
|---|---|---|
| `/favicon.ico` | 16, 32 and 48 px, each a PNG inside the ICO | a browser that asks without a link, and Google Search |
| `/favicon-48.png` · `/favicon-32.png` · `/favicon-16.png` | as named | Google Search (48 px or larger is what it recommends), older browsers |
| `/apple-touch-icon.png` | 180 px | a phone's home screen (iOS) |

Every page's head links them beside the SVG, so a tab, a bookmark, a home screen and a search result all show the
same mark. The icon is fitted into the square and centred on transparency, so an SVG that is not square keeps its
proportions. An app with no `app.Icon` gets the platform's icon at every one of these addresses.

### A page's own icon   {#per-page}
`head { Icon = Art.Kettle; }` gives one page its own icon. That page links `/favicon.svg?icon=kettle`, which serves that
asset. After a client navigation, the tab's icon follows the page and returns to the app's icon on a page without its
own. `?icon=` serves only the app's own art, which is public chrome the app already ships.

## Examples       {#examples}

### An app with its own icon, and one page with another   {#example}
```osy title="the app's mark in every tab, and one page's own" test app=arcade
app.Icon = Art.LogoFull;                   // art/logo_full.svg

[Route("/credits")]
[AllowAnonymous]
[Title("Credits")]
component Credits() { render { Text("Made with Osy#"); } }

[Route("/credits/board")]
[AllowAnonymous]
[Title("The board")]
component CreditsBoard() {
  head { Icon = Art.Hexgrid; }             // art/hexgrid.svg, on this page only
  render { Text("The board"); }
}
```

### What the compiler refuses   {#example-refused}
```osy syntax
app.Icon = "/logo.svg";     // `app.Icon` is one of the SVG files this app ships — `app.Icon = Art.Logo;`
app.Icon = Art.Logoo;       // unknown member — the message lists the Art the app has
```

## See also       {#see-also}
- [head](https://osysharp.com/reference/ui/head/): the rest of what a page tells a browser and a crawler.
- [SVG assets](https://osysharp.com/reference/ui/svg-assets/): the `Art` vocabulary, and how an SVG file becomes one.
- [moved addresses (app.Redirects)](https://osysharp.com/reference/config/redirects/): moved addresses, the other app-wide setting a crawler reads.
