Skip to content

DOCS-3472: Add documentation for Viam Apps #4335

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions assets/scss/_styles_project.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3364,6 +3364,10 @@ div.tablestep > table td, div.tablestep table td {
margin-left: 1.0rem;
}

.td-content > ol li {
margin-bottom: 0.5rem;
}

.td-content > ul {
padding-left: 1rem;
}
Expand Down
Binary file modified assets/tutorials/air-quality-fleet/get-readings.png
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated but doesn't hurt to keep it here

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions docs/dev/reference/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@ date: "2024-09-18"
# updated: "" # When the content was last entirely checked
---

{{% changelog color="added" title="Build custom Viam applications" date="2025-07-17" %}}

You can now create and use Viam applications to build custom applications that interact with your Viam-powered machines through the Viam SDKs.
For more information, see [Viam applications](/operate/control/viam-applications/).

{{% /changelog %}}

{{% changelog color="added" title="Start modules with a TCP connection" date="2025-07-14" %}}

You can now configure to start modules with a TCP connection. See [Module Configuration](/operate/get-started/other-hardware/module-configuration/) for more information.
Expand Down
254 changes: 254 additions & 0 deletions docs/operate/control/viam-applications.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,254 @@
---
title: "Create a Viam application"
linkTitle: "Create a Viam application"
weight: 5
layout: "docs"
type: "docs"
description: "Create and deploy a custom web interface for your machines without managing hosting and authentication."
---

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.

{{<gif webm_src="/spa.webm" mp4_src="/spa.mp4" alt="Sample web application" max-width="500px">}}

## Requirements

{{< expand "Install the Viam CLI and authenticate." >}}
Install the Viam CLI using the option below that matches your system architecture:

{{< readfile "/static/include/how-to/install-cli.md" >}}

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

{{< readfile "/static/include/how-to/auth-cli.md" >}}

{{< /expand >}}

## 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:

```ts {class="line-numbers linkable-line-numbers" data-line=""}
import Cookies from "js-cookie";

let apiKeyId = "";
let apiKeySecret = "";
let host = "";
let machineId = "";

// Extract the machine identifier from the URL
const machineCookieKey = window.location.pathname.split("/")[2];
({
apiKey: { id: apiKeyId, key: apiKeySecret },
machineId: machineId,
hostname: host,
} = JSON.parse(Cookies.get(machineCookieKey)!));
```

For developing your application on localhost, run the following command which will proxy your local app to a machine for testing:

{{< tabs >}}
{{% tab name="Template" %}}

```sh {class="command-line" data-prompt="$" data-output="2-10"}
viam module local-app-testing --app-url http://localhost:<PORT> --machine-id <MACHINE-ID> --machine-api-key <MACHINE-API-KEY> --machine-api-key-id <MACHINE-API-KEY-ID>
```

{{% /tab %}}
{{% tab name="Example" %}}

```sh {class="command-line" data-prompt="$" data-output="2-10"}
viam login
viam module local-app-testing --app-url http://localhost:3000 --machine-id a1b2c3d4-e5f6-7890-abcd-ef1234567890
```

{{% /tab %}}
{{< /tabs >}}

### 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.

{{< table >}}
{{% tablestep number=1 %}}

**Create a <FILE>meta.json</FILE>** file for your module using this template:

{{< tabs >}}
{{% tab name="Template" %}}

```json
{
"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"
}
]
}
```

{{% /tab %}}
{{% tab name="Example" %}}

```json
{
"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"
}
]
}
```

{{% /tab %}}
{{< /tabs >}}

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

{{% expand "Click to view more information on attributes." %}}

<!-- prettier-ignore -->
| Name | Type | Inclusion | Description |
|------|------|-----------|-------------|
| `module_id` | string | **Required** | The module ID, which includes the organization name and the module name. `module_id` uniquely identifies your module. |
| `visibility` | string | **Required** | Must be `"public"`. |
| `description` | string | **Required** | A description of your module and what it provides. |
| `url` | string | Optional | The URL of the GitHub repository containing the source code of the module. |
| `applications` | array | Optional | Objects that provide information about the [applications](/operate/control/viam-applications/) associated with the module. |
| `models` | array | Optional | Empty unless you are shipping the app alongside models. For information on how to add models, see [Integrate other hardware](/operate/get-started/other-hardware/). |

{{% /expand%}}

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

<!-- prettier-ignore -->
| Property | Type | Description |
| ------------ | ------ | ----------- |
| `name` | string | The 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](/operate/reference/naming-modules/#valid-application-identifiers). |
| `type` | string | The type of application (currently only `"single_machine"` is supported). |
| `entrypoint` | string | The path to the HTML entry point for your application. The `entrypoint` field specifies the path to your application's entry point. For example: <ul><li><code>"dist/index.html"</code>: Static content rooted at the `dist` directory</li><li><code>"dist/foo.html"</code>: Static content rooted at the `dist` directory, with `foo.html` as the entry point</li><li><code>"dist/"</code>: Static content rooted at the `dist` directory (assumes `dist/index.html` exists)</li><li><code>"dist/bar/foo.html"</code>: Static content rooted at `dist/bar` with `foo.html` as the entry point</li></ul> |

{{% /tablestep %}}
{{% tablestep number=2 %}}
**Register your module** with Viam:

{{< tabs >}}
{{% tab name="Template" %}}

```sh {class="command-line" data-prompt="$" data-output="3-10"}
viam module create --name="app-name" --public-namespace="namespace"
```

{{% /tab %}}
{{% tab name="Example" %}}

```sh {class="command-line" data-prompt="$" data-output="3-10"}
viam module create --name="air-quality" --public-namespace="naomi"
```

{{% /tab %}}
{{< /tabs >}}

{{% /tablestep %}}
{{% tablestep number=3 %}}

**Package your static files and your <FILE>meta.json</FILE> file and upload them** to the Viam Registry:

```sh {class="command-line" data-prompt="$" data-output="3-10"}
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.

{{% /tablestep %}}
{{< /table >}}

## Access your application

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

```txt
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`.
1. User authenticates with Viam credentials.
1. User selects an organization, location, and machine.
1. User is redirected to `your-app-name_your-public-namespace.viamapplications.com/machine/{machine-id}`.
1. Your application is rendered with access to the selected machine.
The credentials for that one machine are provided in the cookies.

## Example

<!-- For a TypeScript example see [Monitor Air Quality with a Fleet of Sensors](/tutorials/control/air-quality-fleet/). -->

For a React application that shows camera feeds for a machine, see [Viam Camera Viewer](https://github.com/viam-labs/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 capabilities, 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?
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@NickPPC can you re-review this part?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's good


Viam does not currently support using custom domains (`www.mycustomdomain.com[/machine/machine-id]`).
You can, however, redirect from your domain to your Viam application (`www.mycustomdomain.com[/machine/machine-id]` -> `your-app-name_your-public-namespace.viamapplications.com[/machine/machine-id]`).
You can set forwarding up with your DNS provider.

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

<!-- prettier-ignore -->
| Domain | DNS record type | DNS record name | DNS record value |
| ------ | --------------- | --------------- | ---------------- |
| `example.com` | `A` | `@` | `34.8.79.17` |
| `example.com` | `ANAME` or `ALIAS` | `@` | `your-app-name_your-public-namespace.viamapplications.com` |
| `www.examples.com` | `CNAME` | `SUBDOMAIN.example.com` | `your-app-name_your-public-namespace.viamapplications.com` |

To configure a subdomain, set the following values:

<!-- prettier-ignore -->
| Domain | DNS record type | DNS record name | DNS record value |
| ------ | --------------- | --------------- | ---------------- |
| Subdomain (`www.examples.com` or `app.example.com`) | `CNAME` | `SUBDOMAIN.example.com` | `your-app-name_your-public-namespace.viamapplications.com` |
5 changes: 5 additions & 0 deletions docs/operate/control/web-app.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ The TypeScript SDK includes:
- Implementation of the standard component and service APIs to control your hardware and software
- Authentication tools so users can log in securely

{{< alert title="Tip: Host your application on Viam" color="tip" >}}
You can host most apps by [deploying them as Viam applications](/operate/control/viam-applications/).
If your application requires server-side rendering or other back-end functionality, self-host your application instead.
{{< /alert >}}

## Install the TypeScript SDK

Run the following command in your terminal to install the Viam TypeScript SDK:
Expand Down
58 changes: 58 additions & 0 deletions docs/operate/get-started/other-hardware/module-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,64 @@ For any version type other than **Patch (X.Y.Z)**, the module will upgrade as so
If, for example, the module provides a motor component, and the motor is running, it will stop while the module upgrades.
{{% /alert %}}

### Module meta.json configuration

When creating a module, you'll need to create a `meta.json` file that defines the module's properties. This file includes information about the module's ID, visibility, models, and other features.

Here's an example of a `meta.json` file:

```json
{
"module_id": "your-namespace:your-module",
"visibility": "public",
"url": "https://github.com/your-org/your-repo",
"description": "Your module description",
"models": [
{
"api": "rdk:component:base",
"model": "your-namespace:your-module:your-model"
}
],
"entrypoint": "run.sh",
"first_run": "setup.sh"
}
```

For modules that include [Viam applications](/operate/control/viam-applications/), you can add the `applications` field:

```json
{
"module_id": "your-namespace:your-module",
"visibility": "public",
"url": "https://github.com/your-org/your-repo",
"description": "Your module description",
"models": [
{
"api": "rdk:component:base",
"model": "your-namespace:your-module:your-model"
}
],
"entrypoint": "run.sh",
"applications": [
{
"name": "your-app-name",
"type": "web",
"entrypoint": "dist/index.html"
}
]
}
```

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

| Property | Type | Description |
| ------------ | ------ | ------------------------------------------------------------------------------------------------- |
| `name` | string | The name of your application, which will be used in the URL (`name.publicnamespace.viamapps.com`) |
| `type` | string | The type of application (currently only `"web"` is supported) |
| `entrypoint` | string | The path to the HTML entry point for your application |

For more information about Viam applications, see the [Viam applications documentation](/operate/control/viam-applications/).

### Environment variables

Each module has access to the following default environment variables.
Expand Down
26 changes: 25 additions & 1 deletion docs/operate/reference/naming-modules.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ description: "Add support for a new component or service model by writing a modu
languages: ["c++"]
viamresources: []
platformarea: ["registry"]
toc_hide: true
toc_hide: false
---

Each modular resource has two associated triplets: an API namespace triplet to indicate which [API](/dev/reference/apis/) it implements, and a model namespace triplet to uniquely identify the modular resource {{< glossary_tooltip term_id="model" text="model" >}}.
Expand Down Expand Up @@ -95,6 +95,30 @@ More requirements:

Determine the model name you want to use based on these requirements, then proceed to the next section.

## Valid application identifiers

If your module includes a [Viam app](/operate/control/viam-app/), you need to define the application name in your module's `meta.json` file.
Application names have the following requirements:

- Application names must be all-lowercase.
- Application names may only use alphanumeric (`a-z` and `0-9`) and hyphen (`-`) characters.
- Application names may not start or end with a hyphen.
- Application names must be unique within your organization's namespace.

The URL for accessing your Viam app will contain your application name:

```txt
https://app-name_your-public-namespace.viamapps.com
```

For example, if your organization namespace is `acme` and your application name is `dashboard`, your application will be accessible at:

```txt
https://dashboard_acme.viamapps.com
```

For more information about Viam apps, see the [Viam apps documentation](/operate/control/viam-app/).

## Create a namespace for your organization

When uploading modules to the Viam Registry, you must set a unique namespace for your organization to associate your module with.
Expand Down
Loading
Loading