-
Notifications
You must be signed in to change notification settings - Fork 48
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
Open
promptless
wants to merge
17
commits into
main
Choose a base branch
from
docs-update-a3ce53e9-1afa-4e47-8e40-7a3998fb4c11-20250521-113348
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
a6bb349
Documentation updates from Promptless
npentrel aa38d51
Update
npentrel 14fad22
Draft
npentrel 660da6e
Update
npentrel 6b62ff7
Update SPA instructions
npentrel 79b1fc4
Move air quality tutorial to separate PR
npentrel c12df67
Cleanup
npentrel 9c78c33
Fix links
npentrel cc31474
Fix more links
npentrel aedca96
Change name
npentrel d587cff
Minor update
npentrel 939bd61
update cachekey
npentrel 503826a
Update based on Bashar's feedback
npentrel 3102de7
Apply suggestions from code review
npentrel 36f207b
Updates
npentrel c0bb95f
Update docs/operate/control/viam-app.md
npentrel 6875ce3
rename
npentrel File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,297 @@ | ||
--- | ||
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 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(); | ||
```` | ||
|
||
5. Copy the resulting script. It will look like this: | ||
|
||
```js {class="line-numbers linkable-line-numbers" data-line=""} | ||
// 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"); | ||
``` | ||
|
||
6. Open the application you are building on localhost and run the resulting script. | ||
7. 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. | ||
|
||
{{< 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. | ||
|
||
## 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 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: | ||
|
||
<!-- 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` | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[opt] Maybe better to emphasize like this since it's not just plain optional, and this is within the integrate hardware section?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It makes that column too long. If anyone makes a mistake with this the CLI will tell them about it and mostly this is auto-generated, so I'm not worried that there will be confusion.