Linking between actions
Just as you'd use <a>
tags to link between HTML pages, you can use Interval's linking APIs to let users navigate between pages and actions. For example, a page might link each row in a table to an "edit" action, or it could conditionally redirect from one action to another.
There are two components to a link: the path, and an optional params
object.
info
An action or page's path will generally be its slug. If you're using file-based routing or have Pages with nested actions, the path will be a combination of the parent's path and the action's slug, separated by a /
. For example, an action with the slug edit
nested under a Page with the slug users
will have the path users/edit
.
To get a full readout of the routes for all of your actions and pages, visit the All actions screen from your dashboard's Settings menu.
Here's an example of two actions that link to each other:
- TypeScript
- JavaScript
// the path to this action is `favorite_color`
import { Action, io } from "@interval/sdk";
export default new Action(async () => {
await io.group([
io.display.markdown(`Choose your favorite color:`),
io.display.link("Blue", {
route: "result",
params: { favoriteColor: "blue" },
}),
io.display.link("Red", {
route: "result",
params: { favoriteColor: "red" },
}),
]);
});
// the path to this action is `result`
import { Action, ctx } from "@interval/sdk";
export default new Action(async () => {
await io.group([
io.display.markdown(`Favorite color is: ${ctx.params.favoriteColor}`),
io.display.link("Go back", {
route: "favorite_color",
}),
]);
});
// the path to this action is `favorite_color`
const { Action, io } = require("@interval/sdk");
module.exports = new Action(async () => {
await io.group([
io.display.markdown(`Choose your favorite color:`),
io.display.link("Blue", {
route: "result",
params: { favoriteColor: "blue" },
}),
io.display.link("Red", {
route: "result",
params: { favoriteColor: "red" },
}),
]);
});
// the path to this action is `result`
const { Action, ctx } = require("@interval/sdk");
module.exports = new Action(async () => {
await io.group([
io.display.markdown(`Favorite color is: ${ctx.params.favoriteColor}`),
io.display.link("Go back", {
route: "favorite_color",
}),
]);
});
Linking within tables
The most common use of links in Interval apps is to link to actions from within rows in display.table. Here's an example table that links to Edit & Delete actions for each row, and requires an id
param in order to run each of them:
- TypeScript
- JavaScript
import { Page, io } from "@interval/sdk";
import { getUsers } from "../../db";
// the path to this page is "users", and the paths of its nested actions will
// be prefixed with "users/".
export default new Page({
name: "Users",
handler: async () => {
const data = await getUsers();
await io.display.table("Users", {
data,
rowMenuItems: row => [
{
label: "Edit",
route: "users/edit",
params: { id: row.id },
},
{
label: "Delete",
theme: "danger",
route: "users/delete",
params: { id: row.id },
},
],
});
},
});
import { Action, ctx } from "@interval/sdk";
import { getUser } from "../../db";
export default new Action(async () => {
if (!ctx.params.id) {
throw new Error("Missing required param: id");
}
const user = await getUser(ctx.params.id);
// ...
});
import { Action, ctx } from "@interval/sdk";
import { getUser } from "../../db";
export default new Action(async () => {
if (!ctx.params.id) {
throw new Error("Missing required param: id");
}
const user = await getUser(ctx.params.id);
// ...
});
const { Page, io } = require("@interval/sdk");
const { getUsers } = require("../../db");
// the path to this page is "users", and the paths of its nested actions will
// be prefixed with "users/".
module.exports = new Page({
name: "Users",
handler: async () => {
const data = await getUsers();
await io.display.table("Users", {
data,
rowMenuItems: row => [
{
label: "Edit",
route: "edit_user",
params: { id: row.id },
},
{
label: "Delete",
theme: "danger",
route: "delete_user",
params: { id: row.id },
},
],
});
},
});
const { Action, ctx } = require("@interval/sdk");
const { getUser } = require("../../db");
module.exports = new Action(async () => {
if (!ctx.params.id) {
throw new Error("Missing required param: id");
}
const user = await getUser(ctx.params.id);
// ...
});
const { Action, ctx } = require("@interval/sdk");
const { getUser } = require("../../db");
module.exports = new Action(async () => {
if (!ctx.params.id) {
throw new Error("Missing required param: id");
}
const user = await getUser(ctx.params.id);
// ...
});