apps/examples/src/examples/configuration/deep-links/README.md
Allow linking to specific parts of a tldraw canvas.
Deep Links are URLs which point to a specific part of a document. We provide a comprehensive set of tools to help you create and manage deep links in your application.
deepLinks optionThe highest-level API for managing deep links is the deepLinks option on the <Tldraw /> component's options prop. This option is designed for manipulating window.location to add a search param which tldraw can use to navigate to a specific part of the document.
e.g. https://my-app.com/document-name?d=v1234.-234.3.21
If you set deepLinks to true e.g. <Tldraw options={{ deepLinks: true }} /> the following default behavior will be enabled:
window.location for a search param called d. If found, it will try to parse the value of this param as a deep link and navigate to that part of the document.window.location to add the latest version of the d param.You can customize this behavior by passing a configuration object as the deepLinks option. e.g.
<Tldraw
options={{
deepLinks: {
// change the param name to `page`
paramName: 'page',
// only link to the current page
getTarget(editor) {
return { type: 'page', pageId: editor.getCurrentPageId() }
},
// log the new search params to the console instead of updating `window.location`
onChange(url) {
console.log('the new search params are', url.searchParams)
},
// set the debounce interval to 100ms instead of 500ms
debounceMs: 100,
},
}}
/>
For full options see the TLDeepLinkOptions API reference.
We expose the core functionality for managing deep links as a set of methods and utilities. This gives you more control e.g. if you prefer not to use search params in the URL.
You can create an isolated deep link string using the createDeepLinkString helper which takes a TLDeepLink descriptor object.
createDeepLinkString({ type: 'page', pageId: 'page:abc123' })
// => 'pabc123'
createDeepLinkString({ type: 'shapes', shapeIds: ['shape:foo', 'shape:bar'] })
// => 'sfoo.bar'
createDeepLinkString({
type: 'viewport',
pageId: 'page:abc123',
bounds: {
x: 0,
y: 0,
w: 1024,
h: 768,
},
})
// => 'v0.0.1024.768.abc123'
If you do prefer to put this in a URL as a query param, you can use the Editor#createDeepLink method.
editor.createDeepLink({ to: { type: 'page', pageId: 'page:abc123' } })
// => 'https://my-app.com/document-name?d=pabc123'
You can parse a deep link string with parseDeepLinkString which returns a TLDeepLink descriptor object.
You can then call Editor#navigateToDeepLink with this descriptor to navigate to the part of the document described by the deep link.
Editor#navigateToDeepLink also can take a plain URL if the deep link is encoded as a query param.
editor.navigateToDeepLink(parseDeepLinkString('pabc123'))
// or pass in a url
editor.navigateToDeepLink({ url: 'https://my-app.com/document-name?d=pabc123' })
// or call without options to use the current `window.location`
editor.navigateToDeepLink()
You can listen for deep link changes with the Editor#registerDeepLinkListener method, which takes the same options as the deepLinks option.
useEffect(() => {
const unlisten = editor.registerDeepLinkListener({
paramName: 'page',
getTarget(editor) {
return { type: 'page', pageId: editor.getCurrentPageId() }
},
onChange(url) {
console.log('the new search params are', url.searchParams)
},
debounceMs: 100,
})
return () => {
unlisten()
}
}, [])
Create a shape on the canvas then pan or zoom. The d param in the URL updates as you go. Copy that URL into a new tab to return to the same view later.