Link target
Display a related value as a link to another Backlit view.
A link target attaches navigation to a field value or a table row. It does not own the content that it decorates. A field can keep any display variant and also have a link.
API
linkTo(
view: Linkable | (() => Linkable),
args?: unknown[] | ((row) => unknown[]),
options?: {
mode?: 'page' | 'modal' | 'drawer'
filters?: GetFiltersFor<View> | ((row) => GetFiltersFor<View>)
}
): LinkTarget
args must match the target view parameters in length and order. A view with no
parameters does not need args. Missing args are an authoring error.
filters sets the state the target view opens with. The keys are the filter
names the view registers at the view scope, and each value is that filter’s
parsed value, the value ctx.parse gives the resolver. TypeScript reads both
from the view definition. Pass a function to read the filters from the record.
linkTo(() => dealList, [], { filters: (row) => ({ stage: [row.stage] }) })
A link in modal or drawer mode carries its filters too. The dialog opens
with them in its own URL.
Basic link target
Pass the target view and read its args from the record that the field uses.
import {
datalist,
defineResource,
fields,
linkTo,
} from '@backlit/sdk'
import { categories, categoryDetail } from './categories.ts'
const products = defineResource('products', [
fields.ref('category', () => categories, {
display: fields.text('name').configure({
link: linkTo(
categoryDetail,
(record: { id: number }) => [record.id]
),
}),
label: 'Category',
}),
])
products.view('detail', () =>
datalist({
category: { id: 7, name: 'Lighting' },
}).setFields(products.pick('category'))
)
export default productsimport { defineResource, fields } from '@backlit/sdk'
export const categories = defineResource('categories', [
fields.number('id'),
fields.text('name', { label: 'Category' }),
])
export const categoryDetail = categories.view(
'detail',
['id'],
() => []
){
"kind": "success",
"status": 200,
"node": {
"kind": "view",
"resource": "products",
"name": "detail",
"slots": {
"content": [
{
"kind": "datalist",
"fields": [
{
"kind": "ref",
"name": "category",
"label": "Category",
"display": {
"kind": "text",
"name": "name",
"label": "",
"link": {
"kind": "link",
"resource": "categories",
"view": "detail"
}
}
}
],
"data": {
"category": {
"value": "Lighting",
"args": [
7
]
}
}
}
]
}
}
}Thunk
Pass a function when two resource modules refer to each other. Backlit reads the view when it creates the protocol node, after both modules are initialized.
import {
datalist,
defineResource,
fields,
linkTo,
} from '@backlit/sdk'
import { categories, categoryDetail } from './categories.ts'
const products = defineResource('products', [
fields.ref('category', () => categories, {
display: fields.text('name').configure({
link: linkTo(
() => categoryDetail,
(record: { id: number }) => [record.id]
),
}),
label: 'Category',
}),
])
products.view('detail', () =>
datalist({
category: { id: 7, name: 'Lighting' },
}).setFields(products.pick('category'))
)
export default productsimport { defineResource, fields } from '@backlit/sdk'
export const categories = defineResource('categories', [
fields.number('id'),
fields.text('name', { label: 'Category' }),
])
export const categoryDetail = categories.view(
'detail',
['id'],
() => []
){
"kind": "success",
"status": 200,
"node": {
"kind": "view",
"resource": "products",
"name": "detail",
"slots": {
"content": [
{
"kind": "datalist",
"fields": [
{
"kind": "ref",
"name": "category",
"label": "Category",
"display": {
"kind": "text",
"name": "name",
"label": "",
"link": {
"kind": "link",
"resource": "categories",
"view": "detail"
}
}
}
],
"data": {
"category": {
"value": "Lighting",
"args": [
7
]
}
}
}
]
}
}
}Args from the record
Use an args callback when the target view needs values from the current record.
import {
datalist,
defineResource,
fields,
linkTo,
} from '@backlit/sdk'
import { categories, categoryDetail } from './categories.ts'
const products = defineResource('products', [
fields.ref('category', () => categories, {
display: fields.text('name').configure({
link: linkTo(
categoryDetail,
(record: { slug: string }) => [record.slug]
),
}),
label: 'Category',
}),
])
products.view('detail', () =>
datalist({
category: { slug: 'lighting', name: 'Lighting' },
}).setFields(products.pick('category'))
)
export default productsimport { defineResource, fields } from '@backlit/sdk'
export const categories = defineResource('categories', [
fields.text('slug'),
fields.text('name', { label: 'Category' }),
])
export const categoryDetail = categories.view(
'detail',
['category'],
() => []
){
"kind": "success",
"status": 200,
"node": {
"kind": "view",
"resource": "products",
"name": "detail",
"slots": {
"content": [
{
"kind": "datalist",
"fields": [
{
"kind": "ref",
"name": "category",
"label": "Category",
"display": {
"kind": "text",
"name": "name",
"label": "",
"link": {
"kind": "link",
"resource": "categories",
"view": "detail"
}
}
}
],
"data": {
"category": {
"value": "Lighting",
"args": [
"lighting"
]
}
}
}
]
}
}
}Use visitTo instead when the target must define a standalone control with its
own text, icon, tooltip, or skip state.