CINXE.COM
Observable Framework
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"> <meta name="generator" content="Observable Framework v1.13.0"> <title>Observable Framework</title> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="preload" as="style" href="https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&family=Spline+Sans+Mono:ital,wght@0,300..700;1,300..700&display=swap" crossorigin> <link rel="preload" as="style" href="./_import/style.c1e75309.css"> <link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&family=Spline+Sans+Mono:ital,wght@0,300..700;1,300..700&display=swap" crossorigin> <link rel="stylesheet" type="text/css" href="./_import/style.c1e75309.css"> <link rel="modulepreload" href="./_observablehq/client.bb40fe2b.js"> <link rel="modulepreload" href="./_observablehq/runtime.9393ab6d.js"> <link rel="modulepreload" href="./_observablehq/stdlib.3f072cd8.js"> <link rel="canonical" href="https://observablehq.com/framework/"> <link rel="apple-touch-icon" href="./_file/observable.1af93621.png"> <link rel="icon" type="image/png" href="./_file/observable.1af93621.png" sizes="32x32"> <script async="" src="https://www.googletagmanager.com/gtag/js?id=G-9B88TP6PKQ"></script> <script>window.dataLayer=window.dataLayer||[]; function gtag(){dataLayer.push(arguments);} gtag('js',new Date()); gtag('config','G-9B88TP6PKQ');</script> <script type="module">/Win/.test(navigator.platform) || Array.from(document.querySelectorAll(".win"), (e) => e.remove())</script> <script type="module"> import "./_observablehq/client.bb40fe2b.js"; </script> <script type="module" async src="https://static.observableusercontent.com/next/project-latest.js"></script></head> <body> <input id="observablehq-sidebar-toggle" type="checkbox" title="Toggle sidebar"> <label id="observablehq-sidebar-backdrop" for="observablehq-sidebar-toggle"></label> <nav id="observablehq-sidebar"> <ol> <label id="observablehq-sidebar-close" for="observablehq-sidebar-toggle"></label> <li class="observablehq-link observablehq-link-active"><a href="./"><span style="display: flex; align-items: center; font-weight: 500; gap: 0.5rem; margin-left: -0.5rem; color: var(--theme-foreground);"> <svg width="24" height="24" viewBox="0 0 21.92930030822754 22.68549919128418" fill="currentColor"> <path d="M10.9646 18.9046C9.95224 18.9046 9.07507 18.6853 8.33313 18.2467C7.59386 17.8098 7.0028 17.1909 6.62722 16.4604C6.22789 15.7003 5.93558 14.8965 5.75735 14.0684C5.56825 13.1704 5.47613 12.2574 5.48232 11.3427C5.48232 10.6185 5.52984 9.92616 5.62578 9.26408C5.7208 8.60284 5.89715 7.93067 6.15391 7.24843C6.41066 6.56618 6.74143 5.97468 7.14438 5.47308C7.56389 4.9592 8.1063 4.54092 8.72969 4.25059C9.38391 3.93719 10.1277 3.78091 10.9646 3.78091C11.977 3.78091 12.8542 4.00021 13.5962 4.43879C14.3354 4.87564 14.9265 5.49454 15.3021 6.22506C15.6986 6.97704 15.9883 7.7744 16.1719 8.61712C16.3547 9.459 16.447 10.3681 16.447 11.3427C16.447 12.067 16.3995 12.7593 16.3035 13.4214C16.2013 14.1088 16.0206 14.7844 15.7644 15.437C15.4994 16.1193 15.1705 16.7108 14.7739 17.2124C14.3774 17.714 13.8529 18.1215 13.1996 18.4349C12.5463 18.7483 11.8016 18.9046 10.9646 18.9046ZM12.8999 13.3447C13.4242 12.8211 13.7159 12.0966 13.7058 11.3427C13.7058 10.5639 13.4436 9.89654 12.92 9.34074C12.3955 8.78495 11.7441 8.50705 10.9646 8.50705C10.1852 8.50705 9.53376 8.78495 9.00928 9.34074C8.49569 9.87018 8.21207 10.5928 8.22348 11.3427C8.22348 12.1216 8.48572 12.7889 9.00928 13.3447C9.53376 13.9005 10.1852 14.1784 10.9646 14.1784C11.7441 14.1784 12.3891 13.9005 12.8999 13.3447ZM10.9646 22.6855C17.0199 22.6855 21.9293 17.6068 21.9293 11.3427C21.9293 5.07871 17.0199 0 10.9646 0C4.90942 0 0 5.07871 0 11.3427C0 17.6068 4.90942 22.6855 10.9646 22.6855Z"></path> </svg> Framework </span></a></li> </ol> <div id="observablehq-search"><input type="search" placeholder="Search"></div> <div id="observablehq-search-results"></div> <script>{const o=document.querySelector("#observablehq-search");o.setAttribute("data-shortcut",`${/Mac|iPhone/.test(navigator.platform)?"\u2318":"Alt-"}K`);const t=o.querySelector("input"),r=()=>import("./_observablehq/search.5629c990.js");t.addEventListener("focus",r,{once:!0}),t.addEventListener("keydown",r,{once:!0});const c=document.querySelector("#observablehq-sidebar-toggle");addEventListener("keydown",e=>{(e.code==="KeyK"&&e.metaKey&&!e.altKey&&!e.ctrlKey||e.key==="/"&&!e.metaKey&&!e.altKey&&!e.ctrlKey&&e.target===document.body)&&(c.checked?t.focus():(c.click(),t.focus(),c.click()),t.select(),e.preventDefault())});}</script> <ol> <li class="observablehq-link"><a href="./what-is-framework">What is Framework?</a></li> <li class="observablehq-link"><a href="./getting-started">Getting started</a></li> <li class="observablehq-link"><a href="./deploying">Deploying</a></li> <li class="observablehq-link"><a href="./embeds">Embedding</a></li> </ol> <details> <summary>Reference</summary> <ol> <li class="observablehq-link"><a href="./project-structure">Project structure</a></li> <li class="observablehq-link"><a href="./markdown">Markdown</a></li> <li class="observablehq-link"><a href="./javascript">JavaScript</a></li> <li class="observablehq-link"><a href="./reactivity">Reactivity</a></li> <li class="observablehq-link"><a href="./jsx">JSX</a></li> <li class="observablehq-link"><a href="./imports">Imports</a></li> <li class="observablehq-link"><a href="./data-loaders">Data loaders</a></li> <li class="observablehq-link"><a href="./files">Files</a></li> <li class="observablehq-link"><a href="./sql">SQL</a></li> <li class="observablehq-link"><a href="./themes">Themes</a></li> <li class="observablehq-link"><a href="./page-loaders">Page loaders</a></li> <li class="observablehq-link"><a href="./params">Parameterized routes</a></li> <li class="observablehq-link"><a href="./config">Configuration</a></li> </ol> </details> <details> <summary class="observablehq-link"><a href="./inputs/">Inputs</a></summary> <ol> <li class="observablehq-link"><a href="./inputs/button">Button</a></li> <li class="observablehq-link"><a href="./inputs/checkbox">Checkbox</a></li> <li class="observablehq-link"><a href="./inputs/color">Color</a></li> <li class="observablehq-link"><a href="./inputs/date">Date</a></li> <li class="observablehq-link"><a href="./inputs/file">File</a></li> <li class="observablehq-link"><a href="./inputs/form">Form</a></li> <li class="observablehq-link"><a href="./inputs/radio">Radio</a></li> <li class="observablehq-link"><a href="./inputs/range">Range</a></li> <li class="observablehq-link"><a href="./inputs/search">Search</a></li> <li class="observablehq-link"><a href="./inputs/select">Select</a></li> <li class="observablehq-link"><a href="./inputs/table">Table</a></li> <li class="observablehq-link"><a href="./inputs/text">Text</a></li> <li class="observablehq-link"><a href="./inputs/textarea">Textarea</a></li> <li class="observablehq-link"><a href="./inputs/toggle">Toggle</a></li> </ol> </details> <details> <summary>Libraries</summary> <ol> <li class="observablehq-link"><a href="./lib/arrow">Apache Arrow</a></li> <li class="observablehq-link"><a href="./lib/arquero">Arquero</a></li> <li class="observablehq-link"><a href="./lib/csv">CSV</a></li> <li class="observablehq-link"><a href="./lib/d3">D3</a></li> <li class="observablehq-link"><a href="./lib/deckgl">Deck.gl</a></li> <li class="observablehq-link"><a href="./lib/dot">DOT (Graphviz)</a></li> <li class="observablehq-link"><a href="./lib/duckdb">DuckDB</a></li> <li class="observablehq-link"><a href="./lib/htl">Hypertext Literal</a></li> <li class="observablehq-link"><a href="./lib/leaflet">Leaflet</a></li> <li class="observablehq-link"><a href="./lib/lodash">Lodash</a></li> <li class="observablehq-link"><a href="./lib/mapbox-gl">Mapbox GL JS</a></li> <li class="observablehq-link"><a href="./lib/mermaid">Mermaid</a></li> <li class="observablehq-link"><a href="./lib/xlsx">Microsoft Excel (XLSX)</a></li> <li class="observablehq-link"><a href="./lib/mosaic">Mosaic vgplot</a></li> <li class="observablehq-link"><a href="./lib/generators">Observable Generators</a></li> <li class="observablehq-link"><a href="./lib/plot">Observable Plot</a></li> <li class="observablehq-link"><a href="./lib/shapefile">Shapefile</a></li> <li class="observablehq-link"><a href="./lib/sqlite">SQLite</a></li> <li class="observablehq-link"><a href="./lib/tex">TeX</a></li> <li class="observablehq-link"><a href="./lib/topojson">TopoJSON</a></li> <li class="observablehq-link"><a href="./lib/vega-lite">Vega-Lite</a></li> <li class="observablehq-link"><a href="./lib/zip">ZIP</a></li> </ol> </details> <ol> <li class="observablehq-link"><a href="https://github.com/observablehq/framework/tree/main/examples" target="_blank"><span>Examples</span></a></li> <li class="observablehq-link"><a href="./convert">Converting notebooks</a></li> <li class="observablehq-link"><a href="./contributing">Contributing</a></li> </ol> </nav> <script>{const e=document.querySelector("#observablehq-sidebar"),t=document.querySelector("#observablehq-sidebar-toggle"),r=sessionStorage.getItem("observablehq-sidebar");r?t.checked=r==="true":t.indeterminate=!0;for(const o of document.querySelectorAll("#observablehq-sidebar summary")){const s=o.parentElement;switch(sessionStorage.getItem(`observablehq-sidebar:${o.textContent}`)){case"true":s.open=!0;break;case"false":s.classList.contains("observablehq-section-active")||(s.open=!1);break}}addEventListener("beforeunload",()=>sessionStorage.setItem("observablehq-sidebar-scrolly",`${e.scrollTop}`));const a=sessionStorage.getItem("observablehq-sidebar-scrolly");a!=null&&(e.style.cssText="overflow: hidden;",e.scrollTop=+a,e.style.cssText="");}</script> <div id="observablehq-center"> <header id="observablehq-header"> <div style="display: flex; flex-grow: 1; align-items: center; justify-content: space-between; white-space: nowrap;"> <div> <a href="./" class="hide-if-sidebar" style="display: flex; align-items: center; gap: 0.5rem;"> <svg width="24" height="24" viewBox="0 0 21.92930030822754 22.68549919128418" fill="currentColor"> <path d="M10.9646 18.9046C9.95224 18.9046 9.07507 18.6853 8.33313 18.2467C7.59386 17.8098 7.0028 17.1909 6.62722 16.4604C6.22789 15.7003 5.93558 14.8965 5.75735 14.0684C5.56825 13.1704 5.47613 12.2574 5.48232 11.3427C5.48232 10.6185 5.52984 9.92616 5.62578 9.26408C5.7208 8.60284 5.89715 7.93067 6.15391 7.24843C6.41066 6.56618 6.74143 5.97468 7.14438 5.47308C7.56389 4.9592 8.1063 4.54092 8.72969 4.25059C9.38391 3.93719 10.1277 3.78091 10.9646 3.78091C11.977 3.78091 12.8542 4.00021 13.5962 4.43879C14.3354 4.87564 14.9265 5.49454 15.3021 6.22506C15.6986 6.97704 15.9883 7.7744 16.1719 8.61712C16.3547 9.459 16.447 10.3681 16.447 11.3427C16.447 12.067 16.3995 12.7593 16.3035 13.4214C16.2013 14.1088 16.0206 14.7844 15.7644 15.437C15.4994 16.1193 15.1705 16.7108 14.7739 17.2124C14.3774 17.714 13.8529 18.1215 13.1996 18.4349C12.5463 18.7483 11.8016 18.9046 10.9646 18.9046ZM12.8999 13.3447C13.4242 12.8211 13.7159 12.0966 13.7058 11.3427C13.7058 10.5639 13.4436 9.89654 12.92 9.34074C12.3955 8.78495 11.7441 8.50705 10.9646 8.50705C10.1852 8.50705 9.53376 8.78495 9.00928 9.34074C8.49569 9.87018 8.21207 10.5928 8.22348 11.3427C8.22348 12.1216 8.48572 12.7889 9.00928 13.3447C9.53376 13.9005 10.1852 14.1784 10.9646 14.1784C11.7441 14.1784 12.3891 13.9005 12.8999 13.3447ZM10.9646 22.6855C17.0199 22.6855 21.9293 17.6068 21.9293 11.3427C21.9293 5.07871 17.0199 0 10.9646 0C4.90942 0 0 5.07871 0 11.3427C0 17.6068 4.90942 22.6855 10.9646 22.6855Z"></path> </svg> Framework </a> </div> <div style="display: flex; align-items: center; gap: 1rem; font-size: 14px; "> <a class="hide-if-small" target="_blank" title="1.13.0 release notes" href="https://github.com/observablehq/framework/releases" rel="noopener noreferrer"><span>1.13.0</span></a> <a class="hide-if-small" target="_blank" data-decoration="★" title="2,585 GitHub stars" href="https://github.com/observablehq/framework" rel="noopener noreferrer"><span>GitHub️ 2.6k</span></a> <a class="hide-if-large" target="_blank" title="2,585 GitHub stars" href="https://github.com/observablehq/framework" rel="noopener noreferrer"> <svg xmlns="http://www.w3.org/2000/svg" width="21" height="21" viewBox="0 0 21 21" fill="none"> <path d="M19.625 5.60534C18.7083 4.03477 17.4649 2.79135 15.8945 1.87479C14.3238 0.958185 12.6091 0.5 10.7492 0.5C8.88947 0.5 7.17422 0.958325 5.60388 1.87479C4.0333 2.7913 2.78997 4.03477 1.87332 5.60534C0.956814 7.17587 0.498535 8.89089 0.498535 10.7504C0.498535 12.984 1.15021 14.9926 2.4539 16.7766C3.75744 18.5607 5.44142 19.7952 7.50571 20.4803C7.746 20.5249 7.92388 20.4936 8.03954 20.387C8.15524 20.2804 8.21302 20.1467 8.21302 19.9868C8.21302 19.9601 8.21073 19.7199 8.20629 19.266C8.20171 18.8122 8.19956 18.4162 8.19956 18.0783L7.89256 18.1315C7.69682 18.1673 7.44989 18.1825 7.15178 18.1782C6.8538 18.174 6.54446 18.1428 6.22419 18.0847C5.90377 18.0272 5.60575 17.8937 5.32988 17.6846C5.05416 17.4755 4.85842 17.2018 4.74272 16.8639L4.60925 16.5568C4.52029 16.3523 4.38023 16.1251 4.18888 15.8761C3.99754 15.6269 3.80405 15.458 3.60831 15.369L3.51486 15.3021C3.45259 15.2577 3.39481 15.204 3.34138 15.1418C3.28799 15.0796 3.24802 15.0173 3.22132 14.955C3.19458 14.8926 3.21674 14.8414 3.28804 14.8012C3.35933 14.761 3.48817 14.7416 3.67512 14.7416L3.94196 14.7814C4.11993 14.8171 4.34007 14.9236 4.60266 15.1017C4.86511 15.2796 5.08085 15.5109 5.24994 15.7956C5.4547 16.1605 5.7014 16.4385 5.99072 16.6299C6.27982 16.8212 6.5713 16.9167 6.86488 16.9167C7.15846 16.9167 7.41203 16.8945 7.62567 16.8502C7.83908 16.8057 8.0393 16.7388 8.22625 16.6499C8.30633 16.0535 8.52437 15.5953 8.88017 15.275C8.37304 15.2217 7.9171 15.1414 7.51212 15.0347C7.10736 14.9278 6.6891 14.7544 6.25761 14.5139C5.82589 14.2738 5.46774 13.9756 5.18309 13.6198C4.89839 13.2639 4.66474 12.7966 4.48247 12.2183C4.3001 11.6399 4.20889 10.9726 4.20889 10.2163C4.20889 9.13941 4.56044 8.22304 5.26341 7.46665C4.93411 6.65705 4.96519 5.74947 5.35676 4.744C5.61482 4.66382 5.9975 4.72399 6.50463 4.92412C7.01186 5.12434 7.38323 5.29587 7.61912 5.43808C7.85502 5.58024 8.04402 5.70071 8.18642 5.79842C9.01411 5.56715 9.86825 5.45149 10.7491 5.45149C11.6299 5.45149 12.4843 5.56715 13.312 5.79842L13.8192 5.47823C14.166 5.26459 14.5756 5.06881 15.0469 4.89083C15.5185 4.71295 15.8791 4.66396 16.1284 4.74414C16.5286 5.74966 16.5643 6.65719 16.2349 7.46679C16.9378 8.22318 17.2895 9.13978 17.2895 10.2164C17.2895 10.9727 17.198 11.6421 17.0159 12.225C16.8336 12.808 16.5979 13.2749 16.3088 13.6265C16.0194 13.9781 15.659 14.274 15.2275 14.5141C14.7959 14.7544 14.3775 14.9278 13.9728 15.0347C13.5678 15.1415 13.1119 15.2219 12.6047 15.2752C13.0673 15.6755 13.2986 16.3073 13.2986 17.1704V19.9864C13.2986 20.1464 13.3542 20.2799 13.4656 20.3867C13.5768 20.4932 13.7524 20.5246 13.9927 20.4799C16.0573 19.7949 17.7413 18.5603 19.0448 16.7762C20.3481 14.9922 21 12.9837 21 10.75C20.9996 8.89075 20.541 7.17587 19.625 5.60534Z" fill="currentColor"></path> </svg></a> <script async="" defer="" src="https://static.observablehq.com/assets/components/observable-made-by.js"></script> <observable-made-by> </observable-made-by></div> </div> </header> <aside id="observablehq-toc" data-selector="h1:not(:first-of-type)[id], h2:first-child[id], :not(h1) + h2[id]"> <nav> </nav> </aside> <main id="observablehq-main" class="observablehq"> <style> .hero { margin: 4rem 0; text-wrap: balance; } .hero h1 { font-size: 56px; max-width: none; min-width: min-content; line-height: 1; margin: 2rem 0; } .hero h2 { font-style: normal; font-size: 18px; line-height: normal; color: var(--theme-foreground-muted); } .hero .observablehq-pre-container, .hero pre:not(.observablehq-pre-container pre) { margin: 1rem 0; } .cta { display: flex; align-items: center; gap: 2rem; } @container not (min-width: 560px) { .cta { flex-direction: column; align-items: start; gap: 0; } .cta .observablehq-pre-container, .cta pre:not(.observablehq-pre-container pre) { width: 100%; } } .gallery { margin: 4rem -1rem; gap: 2rem; max-width: calc(640px + 2rem); } .gallery a { display: flex; flex-direction: column; align-items: center; gap: 0.5rem; } .gallery img { max-width: 100%; border-radius: 8px; box-shadow: 0 0 0 0.75px rgba(128, 128, 128, 0.2), 0 6px 12px 0 rgba(0, 0, 0, 0.2); aspect-ratio: 2500 / 1900; } @media (prefers-color-scheme: dark) { .gallery img { box-shadow: 0 0 0 0.75px rgba(128, 128, 128, 0.2), 0 6px 12px 0 rgba(0, 0, 0, 0.4); } } .gallery a:not(:hover, :focus) { color: var(--theme-foreground-muted); } .gallery a:hover img, .gallery a:focus img { box-shadow: 0 0 0 0.75px var(--theme-foreground-focus), 0 6px 12px 0 rgba(0, 0, 0, 0.2); } .gallery figcaption { font-size: 12px; color: inherit; } .arrow { font-weight: 500; } .arrow::after { content: "→"; display: inline-block; margin-left: 0.25rem; } </style> <div class="hero"> <h1>The best dashboards are built with <span style="color: var(--theme-foreground-focus);">code.</span></h1> <h2>Create fast, beautiful data apps, dashboards, and reports from the command line. Write Markdown, JavaScript, SQL, Python, R… and any language you like. Free and open-source.</h2> <div class="cta"> <pre data-copy="">npx <span class="win">"</span>@observablehq/framework@latest<span class="win">"</span> create</pre> <a href="./getting-started" class="small arrow" style="color: var(--theme-foreground-focus);">Get started</a> </div> </div> <div class="gallery grid grid-cols-2"> <a href="https://observablehq.observablehq.cloud/framework-example-api/" target="_blank" rel="noopener noreferrer"> <picture> <source srcset="./_file/assets/api.a0b1891e.webp" media="(prefers-color-scheme: dark)"> <img src="./_file/assets/api-dark.4aad268c.webp"> </picture> <div class="small arrow">Analyzing web logs</div> </a> <a href="https://observablehq.observablehq.cloud/framework-example-plot/" target="_blank" rel="noopener noreferrer"> <picture> <source srcset="./_file/assets/plot.3f8ae56a.webp" media="(prefers-color-scheme: dark)"> <img src="./_file/assets/plot-dark.e3955bf0.webp"> </picture> <div class="small arrow">Observable Plot downloads</div> </a> <a href="https://observablehq.observablehq.cloud/framework-example-mortgage-rates/" target="_blank" rel="noopener noreferrer"> <picture> <source srcset="./_file/assets/mortgage-rates.e3ed138a.webp" media="(prefers-color-scheme: dark)"> <img src="./_file/assets/mortgage-rates-dark.3cddf030.webp"> </picture> <div class="small arrow">Fixed-rate mortgages</div> </a> <a href="https://observablehq.observablehq.cloud/framework-example-eia/" target="_blank" rel="noopener noreferrer"> <picture> <source srcset="./_file/assets/eia.8fff1dbb.webp" media="(prefers-color-scheme: dark)"> <img src="./_file/assets/eia-dark.bb917b40.webp"> </picture> <div class="small arrow">U.S. electricity grid</div> </a> </div> <p><strong>Observable Framework</strong> is an <a href="https://github.com/observablehq/framework" target="_blank" rel="noopener noreferrer">open-source</a> static site generator for data apps, dashboards, reports, and more. Framework includes a preview server for local development, and a command-line interface for automating builds & deploys.</p> <p>You write simple <a href="./markdown">Markdown</a> pages — with interactive charts and inputs in <a href="./javascript">reactive JavaScript</a>, and with data snapshots generated by <a href="./data-loaders">data loaders</a> in <em>any</em> programming language (SQL, Python, R, and more) — and Framework compiles it into a static site with instant page loads for a great user experience. Since everything is just files, you can use your preferred editor and source control, write unit tests, share code with other apps, integrate with CI/CD, and host apps anywhere.</p> <p>Framework includes thoughtfully-designed <a href="./themes">themes</a>, <a href="./markdown#grids">grids</a>, and <a href="./imports">libraries</a> to help you build displays of data that look great on any device, including <a href="./lib/plot">Observable Plot</a>, <a href="./lib/d3">D3</a>, <a href="./lib/mosaic">Mosaic</a>, <a href="./lib/vega-lite">Vega-Lite</a>, <a href="./lib/dot">Graphviz</a>, <a href="./lib/mermaid">Mermaid</a>, <a href="./lib/leaflet">Leaflet</a>, <a href="./lib/tex">KaTeX</a>, and myriad more. And for working with data in the client, there’s <a href="./lib/duckdb">DuckDB</a>, <a href="./lib/arquero">Arquero</a>, <a href="./lib/sqlite">SQLite</a>, and more, too.</p> <p>Want the best dashboards? <a href="./getting-started">Get started now.</a></p> </main> <footer id="observablehq-footer"> <nav><a rel="next" href="./what-is-framework"><span>What is Framework?</span></a></nav> <div>© 2024 Observable, Inc.</div> </footer> </div> </body> </html>