Skip to main content

Asset canister overview

Beginner
Concept

Dapps often utilize a frontend interface to facilitate user interaction with the application through elements such as a dashboard, account page, media player, or other assets that are displayed in the web browser. These assets may be in the form of HTML, JavaScript, CSS, or other frontend frameworks like React.

Application frontends are often referred to as asset canisters on ICP, since they are canisters defined as "type": "asset" in the dfx.json file for a project. Projects created by the dfx new command have the option to include a default asset canister named using the project's name and the suffix _frontend, such as hello_world_frontend.

The terms 'asset canister' and 'frontend canister' are often used interchangeably.

Application frontends exist in the following forms:

  • A frontend canister that communicates with backend canister(s) to provide a full-stack dapp.

  • Backend canisters that communicate with an external frontend application that isn't hosted on ICP. To facilitate this communication, agent-js can be used. Learn more about the JS request API.

  • A frontend canister that doesn't communicate with any backend canisters and only provides web assets.

How it works

To host web assets, a canister must implement a method that accepts and consumes an HTTP request, including URL, HTTP method, and header data, then returns an HTTP response, including request status, header data, and body content. This method can return HTML, CSS, and JavaScript content in the HTTP response.

When a canister is configured in a project's dfx.json file as "type": "asset", it already contains the boilerplate code necessary to facilitate these HTTP requests. Once a frontend canister is deployed to the mainnet, the frontend interface can be accessed at http://<canister id>.icp0.io and http://<canister id>.raw.icp0.io.

Default settings

By default, all projects created with dfx new have the option to include a frontend canister in the project. This default frontend canister is written in Rust and uses one of the following frontend frameworks: SvelteKit, React, Vue, or Vanilla JS. The user can choose the framework through the dfx new interactive prompt in dfx versions 0.17.0 and newer.

For asset canisters created by dfx new, the default configuration will include:

  • "source": [ "src/hello_frontend/dist" ]: The default subdirectories containing asset files. For assets to be served in the frontend canister, their directories must be included in this source list.

  • "type": "assets": Defines the canister type as assets.

In dfx.json, these default settings will resemble the following:

{
  "canisters": {
    "hello_backend": {
      "main": "src/hello_backend/main.mo",
      "type": "motoko"
    },
    "hello_frontend": {
      "dependencies": [
        "hello_backend"
      ],
      "source": [
        "src/hello_frontend/dist"
      ],
      "type": "assets",
      "workspace": "hello_frontend"
    }
  },
  "defaults": {
    "build": {
      "args": "",
      "packtool": ""
    }
  },
  "output_env_file": ".env",
  "version": 1
}

Motoko asset canisters

The Motoko server and certified HTTP packages can be used for creating asset canisters using the Motoko language.

Rust asset canisters

The ic-asset Rust crate can be used to develop your project's frontend canister.

Additionally, the ic-http-certification crate can be used to:

  • Serve certified assets from the same canister as their primary “backend” canister.

  • Embed assets directly into a canister’s Wasm rather than uploading them at runtime.

  • Create custom routing logic, such as:

    • Serving 404 pages in multi-page apps.

    • Serving multiple frontends from the same canister.

    • Certify more complex caching or streaming scenarios.

Other third-party options for serving assets include:

TypesScript asset canisters

The Express HTTP server package via Azle can be used to create asset canisters in TypeScript.

Limitations

The frontend canister can host roughly 1GiB in static files. It is recommended that you distribute your files across multiple canisters if the total size of all your assets begins to exceed this amount. Once you exceed this figure, your canister may fail to upgrade.

Dynamic URLs

Dynamic URLs are currently not supported by the default frontend canister.

If a developer would like to support dynamic URLs, custom logic can be implemented using third-party options.

404 pages and aliasing

You can use the ic-http-certification Rust crate for serving 404 pages or configuring redirects through the crate's wildcard function, such as:

use ic_http_certification::HttpCertificationPath;

let path = HttpCertificationPath::wildcard("/js");

404 pages can only be served as raw content currently.

Learn more about the HTTP certification library.

Resources

Next steps

Learn how to use and customize the default frontend canister.