Create a Viam application

Create and deploy a custom web interface for your machines without managing hosting and authentication. Once deployed, your application is accessible from a dedicated URL (appname_publicnamespace.viamapplications.com), and hosting and authentication is handled for you.

Users log into your application and select a machine they have access to. The application then renders your custom interface for interacting with the user’s machine.

Requirements

Install the Viam CLI and authenticate.

Install the Viam CLI using the option below that matches your system architecture:

To download the Viam CLI on a macOS computer, install brew and run the following commands:

brew tap viamrobotics/brews
brew install viam

To download the Viam CLI on a Linux computer with the aarch64 architecture, run the following commands:

sudo curl -o /usr/local/bin/viam https://storage.googleapis.com/packages.viam.com/apps/viam-cli/viam-cli-stable-linux-arm64
sudo chmod a+rx /usr/local/bin/viam

To download the Viam CLI on a Linux computer with the amd64 (Intel x86_64) architecture, run the following commands:

sudo curl -o /usr/local/bin/viam https://storage.googleapis.com/packages.viam.com/apps/viam-cli/viam-cli-stable-linux-amd64
sudo chmod a+rx /usr/local/bin/viam

You can also install the Viam CLI using brew on Linux amd64 (Intel x86_64):

brew tap viamrobotics/brews
brew install viam

Download the binary and run it directly to use the Viam CLI on a Windows computer.

If you have Go installed, you can build the Viam CLI directly from source using the go install command:

go install go.viam.com/rdk/cli/viam@latest

To confirm viam is installed and ready to use, issue the viam command from your terminal. If you see help instructions, everything is correctly installed. If you do not see help instructions, add your local go/bin/* directory to your PATH variable. If you use bash as your shell, you can use the following command:

echo 'export PATH="$HOME/go/bin:$PATH"' >> ~/.bashrc

For more information see install the Viam CLI.

Then authenticate your CLI session with Viam using one of the following options:

viam login

This will open a new browser window with a prompt to start the authentication process. If a browser window does not open, the CLI will present a URL for you to manually open in your browser. Follow the instructions to complete the authentication process.

Use your organization, location, or machine part API key and corresponding API key ID in the following command:

viam login api-key --key-id <api-key-id> --key <organization-api-key-secret>

Build a custom web interface

You can build a custom web interface to access your machines using your preferred framework like React, Vue, Angular, or others.

Access machines from your application

When logging into a Viam application and selecting a machine to use it with, the machine’s API key is stored as a cookie. You can access the data from your browser’s cookies as follows:

import Cookies from "js-cookie";

let apiKeyId = "";
let apiKeySecret = "";
let hostname = "";
let machineId = "";

machineCookie = window.location.pathname.split("/")[2];
({
  id: apiKeyId,
  key: apiKeySecret,
  hostname: hostname,
  machineId: machineId
} = JSON.parse(Cookies.get(machineCookie)!));

For developing your application on localhost, add the same information to your browser's cookies:

1. Navigate to [Camera Viewer](https://camera-viewer_naomi.viamapplications.com/).
2. Log in and select the machine you'd like to use for testing.
3. Open Developer Tools and go to the console.
4. Execute the following JavaScript to obtain the cookies you need:

   ```js {class="line-numbers linkable-line-numbers" data-line=""}
   function generateCookieSetterScript() {
     // Get all cookies from current page
     const currentCookies = document.cookie.split(";");
     let cookieSetterCode = "// Cookie setter script for localhost\n";
     cookieSetterCode +=
       "// Copy and paste this entire script into your browser console when on localhost\n\n";

     // Process each cookie
     let cookieCount = 0;
     currentCookies.forEach((cookie) => {
       if (cookie.trim()) {
         // Extract name and value from the cookie
         const [name, value] = cookie.trim().split("=");

         // Add code to set this cookie
         cookieSetterCode += `document.cookie = "${name}=${value}; path=/";\n`;
         cookieCount++;
       }
     });

     // Add summary comment
     cookieSetterCode += `\nconsole.log("Set ${cookieCount} cookies on localhost");\n`;

     // Display the generated code
     console.log(cookieSetterCode);

     // Create a textarea element to make copying easier
     const textarea = document.createElement("textarea");
     textarea.value = cookieSetterCode;
     textarea.style.position = "fixed";
     textarea.style.top = "0";
     textarea.style.left = "0";
     textarea.style.width = "100%";
     textarea.style.height = "250px";
     textarea.style.zIndex = "9999";
     document.body.appendChild(textarea);
     textarea.focus();
     textarea.select();
   }

   // Execute the function
   generateCookieSetterScript();
  1. Copy the resulting script. It will look like this:

    // Cookie setter script for localhost
    // Copy and paste this entire script into your browser console when on localhost
    
    document.cookie = "<SECRET COOKIE INFO>; path=/";
    document.cookie = "machinesWhoseCredentialsAreStored=<MACHINE ID>; path=/";
    
    console.log("Set 2 cookies on localhost");
    
  2. Open the application you are building on localhost and run the resulting script.

  3. Reload your application.

Configure routing

When using your deployed application, static files will be accessible at https://your-app-name_your-public-namespace.viamapplications.com/machine/<machine-id>/. If your HTML file loads other files, use relative paths to ensure your files are accessible.

Deploy your web interface as a Viam application

To deploy your application with Viam you must package it as a module and upload it using the Viam CLI.

1

Create a meta.json file for your module using this template:

{
  "module_id": "your-namespace:your-module",
  "visibility": "public",
  "url": "https://github.com/your-org/your-repo",
  "description": "Your module description",
  "applications": [
    {
      "name": "your-app-name",
      "type": "single_machine",
      "entrypoint": "dist/index.html"
    }
  ]
}
{
  "module_id": "acme:dashboard",
  "visibility": "public",
  "url": "https://github.com/acme/dashboard",
  "description": "An example dashboard for a fictitious company called Acme.",
  "applications": [
    {
      "name": "dashboard",
      "type": "single_machine",
      "entrypoint": "dist/index.html"
    }
  ]
}

This file specifies the contents of the module. It is required for your module.

Click to view more information on attributes.
NameTypeInclusionDescription
module_idstringRequiredThe module ID, which includes the organization name and the module name. module_id uniquely identifies your module.
visibilitystringRequiredMust be "public".
descriptionstringRequiredA description of your module and what it provides.
urlstringOptionalThe URL of the GitHub repository containing the source code of the module.
applicationsarrayOptionalObjects that provide information about the applications associated with the module.
modelsarrayOptionalEmpty unless you are shipping the app alongside models. For information on how to add models, see Integrate other hardware.

The applications field is an array of application objects with the following properties:

PropertyTypeDescription
namestringThe name of your application, which will be a part of the application’s URL (name_publicnamespace.viamapplications.com). For more information on valid names see Valid application identifiers.
typestringThe type of application (currently only "single_machine" is supported).
entrypointstringThe path to the HTML entry point for your application. The entrypoint field specifies the path to your application’s entry point. For example:
  • “dist/index.html”: Static content rooted at the dist directory
  • “dist/foo.html”: Static content rooted at the dist directory, with foo.html as the entry point
  • “dist/": Static content rooted at the dist directory (assumes dist/index.html exists)
  • “dist/bar/foo.html”: Static content rooted at dist/bar with foo.html as the entry point
2

Register your module with Viam:

viam module create --name="app-name" --public-namespace="namespace"
viam module create --name="air-quality" --public-namespace="naomi"
3

Package your static files and your meta.json file and upload them to the Viam Registry:

tar -czvf module.tar.gz <static-website-files> meta.json
viam module upload --upload=module.tar.gz --platform=any --version=0.0.1

For subsequent updates run these commands again with an updated version number.

Access your application

After uploading your module with the application configuration, your application will be available at:

https://your-app-name_your-public-namespace.viamapplications.com

Users will be prompted to authenticate with their Viam credentials before accessing your application:

  1. User navigates to your-app-name_your-public-namespace.viamapplications.com.
  2. User authenticates with Viam credentials.
  3. User selects an organization, location, and machine.
  4. User is redirected to your-app-name_your-public-namespace.viamapplications.com/machine/{machine-id}.
  5. Your application is rendered with access to the selected machine.

Example

For a React application that shows camera feeds for a machine, see Viam Camera Viewer.

Limitations

  • Applications currently only support single-machine applications.
  • All modules with applications must have public visibility.
  • The page will always render the latest version.
  • Browsers with cookies disabled are not supported.
  • Viam applications serve static files. If you are building an application with server-side rendering or need other back-end capabilites, Viam applications is not the right choice.

Security considerations

  • Customer applications are stored publicly on the internet, so avoid uploading sensitive information in your application code or assets.
  • API keys and secrets are stored in the browser’s cookies.
  • Users authenticate with FusionAuth.

FAQ

Can I use a custom domain?

If you want to serve your side from a domain other than your-app-name_your-public-namespace.viamapplications.com, you can set this up with your DNS provider.

To configure an apex domain (example.com) and the www subdomain, set the following values:

DomainDNS record typeDNS record nameDNS record value
example.comA@34.8.79.17
example.comANAME or ALIAS@your-app-name_your-public-namespace.viamapplications.com
www.examples.comCNAMESUBDOMAIN.example.comyour-app-name_your-public-namespace.viamapplications.com

To configure a subdomain, set the following values:

DomainDNS record typeDNS record nameDNS record value
Subdomain (www.examples.com or app.example.com)CNAMESUBDOMAIN.example.comyour-app-name_your-public-namespace.viamapplications.com