diff --git a/src/app.d.ts b/src/app.d.ts index 405eda2..2da67a0 100644 --- a/src/app.d.ts +++ b/src/app.d.ts @@ -6,6 +6,12 @@ declare global { // interface Locals {} interface PageData { pageTitle?: string; + /** Full `` override; takes precedence over `pageTitle`. */ + metaTitle?: string; + /** Meta description for the current page. */ + metaDescription?: string; + /** Comma separated meta keywords for the current page. */ + metaKeywords?: string; } // interface PageState {} // interface Platform {} diff --git a/src/app.html b/src/app.html index e404bba..5744d25 100644 --- a/src/app.html +++ b/src/app.html @@ -1,17 +1,28 @@ <!doctype html> -<html lang="en"> +<html lang="%lang%"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> + <meta + name="theme-color" + content="#16a34a" /> <link rel="icon" - href="/branch.svg" + href="%sveltekit.assets%/branch.svg" type="image/svg+xml" /> + <link + rel="apple-touch-icon" + href="%sveltekit.assets%/branch.svg" /> + <link + rel="manifest" + href="%sveltekit.assets%/manifest.webmanifest" /> %sveltekit.head% </head> - <body data-sveltekit-preload-data="hover" class="bg-background"> + <body + data-sveltekit-preload-data="hover" + class="bg-background"> <div style="display: contents">%sveltekit.body%</div> </body> </html> diff --git a/src/lib/i18n/translations/cs.ts b/src/lib/i18n/translations/cs.ts index 2029da0..6e87099 100644 --- a/src/lib/i18n/translations/cs.ts +++ b/src/lib/i18n/translations/cs.ts @@ -441,6 +441,41 @@ const cs: Translation = { }, }, + seo: { + titleDefault: 'Treeline – Interaktivní vizualizace datových struktur a algoritmů', + description: + 'Treeline je bezplatný interaktivní nástroj pro výuku datových struktur a třídicích i vyhledávacích algoritmů. Sledujte každý krok binárních vyhledávacích stromů, AVL, červeno-černých a B-stromů, hald, spojových seznamů, zásobníků, front i třídění jako quicksort, merge sort a heap sort.', + keywords: + 'datové struktury, algoritmy, vizualizace algoritmů, vizualizace datových struktur, třídicí algoritmy, vyhledávací algoritmy, binární vyhledávací strom, AVL strom, červeno-černý strom, B-strom, halda, spojový seznam, zásobník, fronta, bubble sort, selection sort, insertion sort, merge sort, quicksort, heap sort, binární vyhledávání, lineární vyhledávání, informatika, učit se algoritmy interaktivně', + about: 'Zjistěte více o Treeline – bezplatném open-source nástroji pro interaktivní vizualizaci datových struktur a algoritmů, vytvořeném jako diplomová práce.', + dataStructures: { + 'binary-search-tree': + 'Vizualizujte binární vyhledávací strom (BST) krok za krokem. Vkládejte, vyhledávejte a odebírejte hodnoty a sledujte, jak se strom mění v reálném čase.', + 'avl-tree': + 'Interaktivní vizualizace AVL stromu. Sledujte, jak rotace udržují strom vyvážený po každém vložení a odebrání, krok za krokem.', + 'red-black-tree': + 'Interaktivní vizualizace červeno-černého stromu. Sledujte přebarvování a rotace, které udržují strom vyvážený při vkládání a mazání.', + 'b-tree': 'Interaktivní vizualizace B-stromu. Sledujte štěpení uzlů, slučování a posun klíčů při vkládání a odebírání hodnot.', + heap: 'Interaktivní vizualizace binární haldy. Vkládejte hodnoty, odebírejte kořen a sledujte, jak heapify udržuje vlastnost max-haldy.', + 'linked-list': + 'Interaktivní vizualizace spojového seznamu. Vkládejte na začátek či konec, vyhledávejte a odebírejte uzly a sledujte aktualizaci ukazatelů.', + stack: 'Interaktivní vizualizace zásobníku. Pomocí operací push, pop a peek pochopíte princip LIFO (poslední dovnitř, první ven).', + queue: 'Interaktivní vizualizace fronty. Pomocí operací enqueue, dequeue a peek pochopíte princip FIFO (první dovnitř, první ven).', + }, + sorting: { + bubble: 'Vizualizujte bubble sort krok za krokem s ovládáním přehrávání, zvýrazněním pseudokódu a různými rozloženími dat.', + selection: + 'Vizualizujte selection sort krok za krokem s ovládáním přehrávání, zvýrazněním pseudokódu a různými rozloženími dat.', + insertion: + 'Vizualizujte insertion sort krok za krokem s ovládáním přehrávání, zvýrazněním pseudokódu a různými rozloženími dat.', + merge: 'Vizualizujte merge sort krok za krokem s ovládáním přehrávání, zvýrazněním pseudokódu a různými rozloženími dat.', + quick: 'Vizualizujte quicksort krok za krokem s ovládáním přehrávání, zvýrazněním pseudokódu a různými rozloženími dat.', + heap: 'Vizualizujte heap sort krok za krokem s ovládáním přehrávání, zvýrazněním pseudokódu a různými rozloženími dat.', + searching: 'Vizualizujte lineární a binární vyhledávání krok za krokem s nastavitelným cílem a ovládáním přehrávání.', + comparison: 'Porovnejte třídicí algoritmy vedle sebe na různých datových sadách a zvažte porovnání, výměny i rychlost.', + }, + }, + description: { title: 'Popis', noJs: 'Obsah popisu se načítá dynamicky a JavaScript je momentálně vypnutý.', diff --git a/src/lib/i18n/translations/en.ts b/src/lib/i18n/translations/en.ts index 76717fe..3611a41 100644 --- a/src/lib/i18n/translations/en.ts +++ b/src/lib/i18n/translations/en.ts @@ -440,6 +440,42 @@ const en = { }, }, + seo: { + titleDefault: 'Treeline – Interactive Data Structure & Algorithm Visualizer', + description: + 'Treeline is a free, interactive visualizer for learning data structures, sorting, and searching algorithms. Watch every step of binary search trees, AVL, red-black and B-trees, heaps, linked lists, stacks, queues, and sorts like quicksort, merge sort, and heap sort.', + keywords: + 'data structures, algorithms, algorithm visualizer, data structure visualization, sorting algorithms, searching algorithms, binary search tree, AVL tree, red-black tree, B-tree, heap, linked list, stack, queue, bubble sort, selection sort, insertion sort, merge sort, quicksort, heap sort, binary search, linear search, computer science, learn algorithms interactively', + about: "Learn about Treeline, a free and open-source interactive tool for visualizing data structures and algorithms, built as a Master's thesis project.", + dataStructures: { + 'binary-search-tree': + 'Visualize a binary search tree (BST) step by step. Insert, find, and remove values and watch the tree reshape in real time.', + 'avl-tree': + 'Interactive AVL tree visualization. See how rotations keep the tree height-balanced after every insertion and deletion, one step at a time.', + 'red-black-tree': + 'Interactive red-black tree visualization. Follow the recoloring and rotations that keep the tree balanced during inserts and deletes.', + 'b-tree': 'Interactive B-tree visualization. Watch node splits, merges, and key promotions as you insert and remove values.', + heap: 'Interactive binary heap visualization. Insert values, extract the root, and watch heapify maintain the max-heap property.', + 'linked-list': + 'Interactive linked list visualization. Insert at the head or tail, find, and remove nodes while pointers update in real time.', + stack: 'Interactive stack visualization. Push, pop, and peek values to understand last-in, first-out (LIFO) behavior.', + queue: 'Interactive queue visualization. Enqueue, dequeue, and peek values to understand first-in, first-out (FIFO) behavior.', + }, + sorting: { + bubble: 'Visualize bubble sort step by step with playback controls, pseudocode highlighting, and multiple data distributions.', + selection: + 'Visualize selection sort step by step with playback controls, pseudocode highlighting, and multiple data distributions.', + insertion: + 'Visualize insertion sort step by step with playback controls, pseudocode highlighting, and multiple data distributions.', + merge: 'Visualize merge sort step by step with playback controls, pseudocode highlighting, and multiple data distributions.', + quick: 'Visualize quicksort step by step with playback controls, pseudocode highlighting, and multiple data distributions.', + heap: 'Visualize heap sort step by step with playback controls, pseudocode highlighting, and multiple data distributions.', + searching: 'Visualize linear search and binary search step by step, with adjustable targets and playback controls.', + comparison: + 'Compare sorting algorithms side by side across multiple dataset profiles and weigh comparisons, swaps, and speed together.', + }, + }, + description: { title: 'Description', noJs: 'Description content loads dynamically and JavaScript is currently disabled.', diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 0037957..fef96aa 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -4,6 +4,7 @@ import { goto } from '$app/navigation'; import type { Locale } from '$lib/i18n'; + import { SITE_URL } from '$lib/seo/config'; onMount(() => { let locale: Locale = 'en'; @@ -22,6 +23,31 @@ }); </script> +<svelte:head> + <title>Treeline – Interactive Data Structure & Algorithm Visualizer + + + + + + + +

Redirecting...

diff --git a/src/routes/[lang]/+layout.svelte b/src/routes/[lang]/+layout.svelte index 8b45b15..7ddca18 100644 --- a/src/routes/[lang]/+layout.svelte +++ b/src/routes/[lang]/+layout.svelte @@ -3,16 +3,27 @@ import Footer from '$lib/components/Footer.svelte'; import Nav from '$lib/components/Nav.svelte'; - import { setLocaleContext } from '$lib/i18n'; + import Seo from '$lib/components/Seo.svelte'; + import { setLocaleContext, translate } from '$lib/i18n'; + import { SITE_NAME } from '$lib/seo/config'; let { data, children } = $props(); setLocaleContext(data.lang); + + const t = (key: string) => translate(data.lang, key); + + const title = $derived(page.data.metaTitle ?? (page.data.pageTitle ? `${page.data.pageTitle} – ${SITE_NAME}` : t('seo.titleDefault'))); + const description = $derived(page.data.metaDescription ?? t('seo.description')); + const keywords = $derived(page.data.metaKeywords ?? t('seo.keywords')); - - {page.data.pageTitle ? `${page.data.pageTitle} - Treeline` : 'Treeline'} - +