This example demonstrates a full-stack app with a frontend and backend canister, showing how to pass environment variables from the asset canister to the frontend webapp.
This project consists of two canisters:
- backend: a {{backend_type}} canister with its
backend.didfile. - frontend: a {{frontend_type}} webapp deployed in an asset canister.
The @icp-sdk/bindgen library offers a plugin for Vite that generates the TypeScript Candid bindings from the backend.did file. The bindings are generated at build time by Vite and are saved in the frontend/app/src/backend/api/ folder.
The plugin supports hot module replacement, so you can run the frontend in development mode (by running npm run dev in the frontend/app/ folder) and make changes to the Candid declaration file to see the bindings being updated in real time.
See the vite.config.ts file for how the plugin is used.
The project is configured to pass the backend's canister ID to the frontend using a cookie. The environment variables are made available to the frontend JS code that runs in the browser by following this flow:
- During deployment, the
icpCLI sets the backend's canister ID in the frontend canister's (asset canister) environment variables - The asset canister sets a specific cookie (named
ic_env) that contains some environment variables when the assets are uploaded - The asset canister serves the frontend assets with the cookie set
- The frontend JS code uses the
@icp-sdk/core/agent/canister-envmodule to parse the cookie and extract the environment variables
In the App.tsx file, you can see how the frontend can obtain the backend's canister ID from the environment variables and use it to create an actor for the backend canister.
Before you begin, ensure that you have the following installed:
First, start a local network:
icp network start -dThen, deploy both canisters:
icp deployThis command will output something like this:
Syncing canisters:
[backend] ✔ Synced successfully: uqqxf-5h777-77774-qaaaa-cai
[frontend] ✔ Synced successfully: uxrrr-q7777-77774-qaaaq-cai # <- copy this canister id
Open the deployed frontend in a browser. Copy the frontend's canister ID from the output of the icp deploy command and construct the URL in this way: http://<frontend_canister_id>.localhost:8000/.
You can also make direct calls to the backend canister:
icp canister call backend greet '("Internet Computer")'Finally, you can stop the local network with:
icp network stop