URL templating system for dynamically generating URLs from query result values using LiquidJS template syntax.
Lightdash provides URL templating functionality that allows you to embed result values into URLs dynamically. This is useful for creating drill-through links, external integrations, or custom navigation based on query results.
The templating engine uses LiquidJS with custom delimiters (${ and }) and supports referencing both the current cell value and other values in the same result row.
import {
renderTemplatedUrl,
getTemplatedUrlRowDependencies,
type ResultValue,
} from '@lightdash/common';Renders a URL template string by substituting template variables with actual result values.
/**
* Render a URL template with values from a result row
* @param templatedUrl - URL template string with ${} placeholders
* @param value - The current cell's value
* @param row - Complete result row with all field values
* @returns Rendered URL string
* @throws Error if template contains invalid references
*/
function renderTemplatedUrl(
templatedUrl: string,
value: ResultValue,
row: Record<string, Record<string, ResultValue>>
): string;Example:
import { renderTemplatedUrl } from '@lightdash/common';
// Current cell value
const value = {
raw: 'PROD-123',
formatted: 'PROD-123',
};
// Complete result row (nested structure: table -> field -> value)
const row = {
orders: {
order_id: {
raw: 'PROD-123',
formatted: 'PROD-123',
},
order_date: {
raw: '2024-01-15',
formatted: 'January 15, 2024',
},
},
customers: {
customer_name: {
raw: 'Acme Corp',
formatted: 'Acme Corp',
},
},
};
// Template using current value
const url1 = renderTemplatedUrl(
'https://example.com/orders/${value.raw | url_encode }',
value,
row
);
console.log(url1); // 'https://example.com/orders/PROD-123'
// Template using other row values
const url2 = renderTemplatedUrl(
'https://example.com/customer/${row.customers.customer_name.raw | url_encode }/order/${value.raw | url_encode }',
value,
row
);
console.log(url2); // 'https://example.com/customer/Acme+Corp/order/PROD-123'
// Template with formatted values
const url3 = renderTemplatedUrl(
'https://example.com/search?date=${row.orders.order_date.formatted | url_encode }',
value,
row
);
console.log(url3); // 'https://example.com/search?date=January+15%2C+2024'Extracts field dependencies from a URL template to determine which row fields are referenced.
/**
* Extract field names referenced in a URL template
* @param templatedUrl - URL template string to analyze
* @returns Array of field names (in table_field format) that the template depends on
* @throws Error if template contains invalid references
*/
function getTemplatedUrlRowDependencies(templatedUrl: string): string[];Example:
import { getTemplatedUrlRowDependencies } from '@lightdash/common';
// Template using only current value
const deps1 = getTemplatedUrlRowDependencies('https://example.com/id/${value.raw}');
console.log(deps1); // []
// Template using row references
const deps2 = getTemplatedUrlRowDependencies(
'https://example.com/orders/${row.orders.order_id.raw | url_encode }?customer=${row.customers.customer_name.raw | url_encode }'
);
console.log(deps2); // ['orders_order_id', 'customers_customer_name']
// Use dependencies to ensure required fields are in query
const requiredFields = getTemplatedUrlRowDependencies(templateUrl);
console.log('Template requires these fields:', requiredFields);
// Invalid template throws error
try {
getTemplatedUrlRowDependencies('https://example.com/${invalid}');
} catch (error) {
console.error(error.message); // 'Found invalid reference "invalid" in your url template'
}${value.raw} - The raw (unformatted) value of the current cell${value.formatted} - The formatted value of the current cell${row.tablename.fieldname.raw | url_encode } - Raw value from another field in the same row${row.tablename.fieldname.formatted | url_encode } - Formatted value from another field in the same rowRow data is structured as nested objects: row.tablename.fieldname.raw or row.tablename.fieldname.formatted.
Important: Use the | url_encode filter to properly encode values for use in URLs.
value.* or row.*.*. syntaxrow.tablename.fieldname.raw or row.tablename.fieldname.formatted.raw or .formatted| url_encode filter to properly encode values for URLs// Link to detailed view using current value
const detailUrl = 'https://app.example.com/orders/${value.raw | url_encode }';
// Link with multiple parameters from row
const multiParamUrl =
'https://app.example.com/analysis?product=${row.products.product_id.raw | url_encode }&date=${row.orders.order_date.raw | url_encode }';// Jira ticket link
const jiraUrl = 'https://jira.company.com/browse/${value.raw | url_encode }';
// Salesforce record link
const sfUrl =
'https://company.salesforce.com/lightning/r/Account/${row.accounts.account_id.raw | url_encode }/view';
// Google Maps link
const mapsUrl =
'https://www.google.com/maps/search/?api=1&query=${row.locations.latitude.raw | url_encode },${row.locations.longitude.raw | url_encode }';// Search by customer name
const searchUrl =
'https://app.example.com/search?q=${row.customers.customer_name.raw | url_encode }';
// Filter by date range
const filterUrl =
'https://app.example.com/reports?start=${row.orders.start_date.raw | url_encode }&end=${row.orders.end_date.raw | url_encode }';type ResultValue = {
raw: string | number | boolean | null | Date;
formatted: string;
};For complete ResultValue type documentation, see Query Results Types.