Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -124,11 +124,15 @@
"@codemirror/lang-html": "^6.4.11",
"@codemirror/lang-javascript": "^6.2.4",
"@codemirror/state": "^6.5.4",
"@fontsource/inter": "^5.2.8",
"@resvg/resvg-js": "^2.6.2",
"@stackblitz/sdk": "^1.11.0",
"@uiw/codemirror-theme-github": "^4.25.4",
"@webcontainer/api": "^1.6.1",
"ansi_up": "^6.0.6",
"codemirror": "^6.0.2",
"flexsearch": "^0.8.212"
"flexsearch": "^0.8.212",
"satori": "^0.19.2",
"satori-html": "^0.3.2"
}
}
1 change: 0 additions & 1 deletion docs/src/lib/assets/favicon.svg

This file was deleted.

53 changes: 52 additions & 1 deletion docs/src/routes/+layout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import { dev } from '$app/environment';
import { page } from '$app/state';
import { preparePageTransition } from '$lib/page-transitions';

import '@fontsource-variable/inter';
import '../app.css';

Expand Down Expand Up @@ -55,8 +54,60 @@

// View transition for navigation
preparePageTransition();

const defaultDescription =
'Composable Svelte chart components to build a large variety of visualizations';

let pageTitle = $derived(
page.data.metadata?.name ? `${page.data.metadata.name} | LayerChart` : 'LayerChart'
);
let pageDescription = $derived(page.data.metadata?.description ?? defaultDescription);
// TODO: Switch back to dynamic satori-based OG image once Cloudflare compatibility is resolved
// let ogImageUrl = $derived(
// `${page.url.origin}/og?title=${encodeURIComponent(page.data.metadata?.name ?? 'LayerChart')}${page.data.metadata?.description ? `&description=${encodeURIComponent(page.data.metadata.description)}` : `&description=${encodeURIComponent(defaultDescription)}`}${page.data.metadata?.category ? `&component=${encodeURIComponent(page.data.metadata.category)}` : ''}`
// );
let ogImageUrl = $derived(`${page.url.origin}/images/og-image.png`);
</script>

<svelte:head>
<title>{pageTitle}</title>
<meta name="description" content={pageDescription} />

<!-- Open Graph -->
<meta property="og:type" content="website" />
<meta property="og:title" content={pageTitle} />
<meta property="og:description" content={pageDescription} />
<meta property="og:image" content={ogImageUrl} />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
<meta property="og:url" content={page.url.href} />
<meta property="og:site_name" content="LayerChart" />

<!-- Twitter Card -->
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:site" content="@techniq35" />
<meta name="twitter:title" content={pageTitle} />
<meta name="twitter:description" content={pageDescription} />
<meta name="twitter:image" content={ogImageUrl} />

<link rel="icon" href="/favicon.svg" type="image/svg+xml" />

{#if page.url.origin.includes('https')}
<script
defer
src="https://static.cloudflareinsights.com/beacon.min.js"
data-cf-beacon={JSON.stringify({ token: 'aff39463882545fd8cca0adba6afa86e' })}
></script>

<script
async
defer
src="https://us.umami.is/script.js"
data-website-id="98141640-7328-4228-ba7b-2287da133ee9"
></script>
{/if}
</svelte:head>

<!-- Disable data preloading until Svelte async/fork is improved -->
<!-- TODO: might be fixed in 2.49.4 - https://github.com/sveltejs/kit/releases/tag/%40sveltejs%2Fkit%402.49.4 -->
<div data-sveltekit-preload-data="off">
Expand Down
1 change: 1 addition & 0 deletions docs/src/routes/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@
];
</script>


<header class="flex h-16 items-center px-4 py-2">
<a href="/" class="hidden xs:flex invisible md:visible items-center gap-3 w-60 text-xl font-bold">
<Logo class="w-7" />
Expand Down
22 changes: 1 addition & 21 deletions docs/src/routes/docs/+layout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@
import Search from './search/Search.svelte';
import DocsMenu from '$lib/components/DocsMenu.svelte';
import TableOfContents from '$lib/components/TableOfContents.svelte';
import favicon from '$lib/assets/favicon.svg';

import LucideAlignLeft from '~icons/lucide/align-left';
import LucideFilePen from '~icons/lucide/file-pen';
import LucideEllipsisVertical from '~icons/lucide/ellipsis-vertical';
Expand All @@ -35,26 +33,8 @@
// let pageContent = $derived(page.data.content.docs[page.params.slug] ?? {});
let showDrawer = $state(false);
let showSidebar = $state(true);
</script>

<svelte:head>
<link rel="icon" href={favicon} />

{#if page.url.origin.includes('https')}
<script
defer
src="https://static.cloudflareinsights.com/beacon.min.js"
data-cf-beacon={JSON.stringify({ token: 'aff39463882545fd8cca0adba6afa86e' })}
></script>

<script
async
defer
src="https://us.umami.is/script.js"
data-website-id="98141640-7328-4228-ba7b-2287da133ee9"
></script>
{/if}
</svelte:head>
</script>

<div class="absolute top-0 w-screen h-screen background-gradient pointer-events-none"></div>
<div
Expand Down
75 changes: 75 additions & 0 deletions docs/src/routes/og/+server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// TODO: Restore dynamic satori-based OG image generation once Cloudflare compatibility is resolved.
// Blocked by: satori and @resvg/resvg-js not being compatible with Cloudflare Workers.
// Consider switching to @vercel/og which handles Wasm initialization for edge runtimes.
//
// import { render } from 'svelte/server';
// import satori from 'satori';
// import { html } from 'satori-html';
// import { Resvg } from '@resvg/resvg-js';
//
// import InterRegular from '@fontsource/inter/files/inter-latin-400-normal.woff';
// import InterSemibold from '@fontsource/inter/files/inter-latin-600-normal.woff';
// import InterBold from '@fontsource/inter/files/inter-latin-700-normal.woff';
//
// import { dev } from '$app/environment';
// import { read } from '$app/server';
// import type { RequestHandler } from './$types';
//
// import Thumbnail from './Thumbnail.svelte';
//
// const interRegular = read(InterRegular).arrayBuffer();
// const interSemibold = read(InterSemibold).arrayBuffer();
// const interBold = read(InterBold).arrayBuffer();
//
// export const GET: RequestHandler = async ({ url }) => {
// const renderedComponent = render(Thumbnail, {
// props: {
// title: url.searchParams.get('title') ?? '',
// description: url.searchParams.get('description') ?? undefined,
// component: url.searchParams.get('component') ?? undefined
// }
// });
//
// const markup = html(`<style>${renderedComponent.head}</style>${renderedComponent.body}`);
//
// const svg = await satori(markup, {
// width: 1200,
// height: 630,
// fonts: [
// {
// name: 'Inter',
// data: await interRegular,
// weight: 400,
// style: 'normal'
// },
// {
// name: 'Inter',
// data: await interSemibold,
// weight: 600,
// style: 'normal'
// },
// {
// name: 'Inter',
// data: await interBold,
// weight: 700,
// style: 'normal'
// }
// ]
// });
//
// const png = new Resvg(svg, {
// fitTo: {
// mode: 'original'
// }
// })
// .render()
// .asPng();
//
// const response = new Response(new Uint8Array(png), {
// headers: {
// 'Content-Type': 'image/png'
// }
// });
// if (!dev) response.headers.append('Cache-Control', `max-age=${60 * 60 * 24 * 30}, immutable`);
// return response;
// };
48 changes: 48 additions & 0 deletions docs/src/routes/og/Thumbnail.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<script lang="ts">
type Props = {
title: string;
description?: string;
component?: string;
};

let { title, description, component }: Props = $props();
</script>

<div
style="display: flex; flex-direction: column; width: 100%; height: 100%; padding: 64px; background: linear-gradient(135deg, #1e1b4b, #312e81, #4338ca); font-family: Inter;"
>
<div style="display: flex; flex-direction: column; flex: 1;">
<div style="display: flex; align-items: center; margin-bottom: 40px; gap: 16px;">
<span style="display: flex; font-size: 30px; font-weight: 700; color: white;">LayerChart</span
>
{#if component}
<span
style="display: flex; padding: 4px 16px; border-radius: 9999px; font-size: 18px; color: white; background: rgba(255,255,255,0.15);"
>
{component}
</span>
{/if}
</div>

<p style="display: flex; margin-bottom: 24px; font-size: 72px; font-weight: 700; color: white;">
{title}
</p>

{#if description}
<p
style="display: flex; max-width: 900px; font-size: 28px; color: white; opacity: 0.8; line-height: 1.4;"
>
{description}
</p>
{/if}

<div style="display: flex; flex: 1;"></div>

<div
style="display: flex; justify-content: space-between; font-size: 22px; color: rgba(255,255,255,0.6);"
>
<span style="display: flex;">Composable Svelte visualization library</span>
<span style="display: flex;">layerchart.com</span>
</div>
</div>
</div>
29 changes: 29 additions & 0 deletions docs/static/favicon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/static/images/og-image.afdesign
Binary file not shown.
Binary file added docs/static/images/og-image.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions docs/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export default defineConfig({
}) /*, devtoolsJson()*/
],
server: {
// allowedHosts: ['.trycloudflare.com'],
fs: {
allow: ['.live-code']
},
Expand Down Expand Up @@ -95,6 +96,8 @@ export default defineConfig({
// Disabled during tests to avoid "Failed to load source map" warnings (e.g. typescript.js.map)
// Ref: https://github.com/vitest-dev/vitest/issues/6806
noExternal: isTest ? undefined : true,
// satori and @resvg/resvg-js have CJS dependencies that need to be loaded as external
external: ['satori', '@resvg/resvg-js'],
// @dagrejs/dagre is CJS-only and fails with "module is not defined" when
// bundled for SSR. Pre-bundling converts it to ESM so it works both in
// dev and in the production build (where node_modules aren't available).
Expand Down
Loading
Loading