Add translation support for the website (#7277)

This commit is contained in:
Elian Doran 2025-10-13 19:49:27 +03:00 committed by GitHub
commit 016ba1e617
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 410 additions and 143 deletions

View File

@ -14,6 +14,7 @@ usageMatchRegex:
# the `{key}` will be placed by a proper keypath matching regex,
# you can ignore it and use your own matching rules as well
- "[^\\w\\d]t\\(['\"`]({key})['\"`]"
- <Trans\s*i18nKey="({key})"[^>]*>
# A RegEx to set a custom scope range. This scope will be used as a prefix when detecting keys
# and works like how the i18next framework identifies the namespace scope from the

View File

@ -5,7 +5,8 @@
"i18n-ally.keystyle": "nested",
"i18n-ally.localesPaths": [
"apps/server/src/assets/translations",
"apps/client/src/translations"
"apps/client/src/translations",
"apps/website/public/translations"
],
"npm.exclude": [
"**/dist",

View File

@ -8,9 +8,12 @@
"preview": "pnpm build && vite preview"
},
"dependencies": {
"i18next": "25.6.0",
"i18next-http-backend": "3.0.2",
"preact": "10.27.2",
"preact-iso": "2.11.0",
"preact-render-to-string": "6.6.2"
"preact-render-to-string": "6.6.2",
"react-i18next": "16.0.0"
},
"devDependencies": {
"@preact/preset-vite": "2.10.2",

View File

@ -0,0 +1,199 @@
{
"get-started": {
"title": "Get started",
"desktop_title": "Download the desktop application (v{{version}})",
"architecture": "Architecture:",
"older_releases": "See older releases",
"server_title": "Set up a server for access on multiple devices"
},
"hero_section": {
"title": "Organize your thoughts. Build your personal knowledge base.",
"subtitle": "Trilium is an open-source solution for note-taking and organizing a personal knowledge base. Use it locally on your desktop, or sync it with your self-hosted server to keep your notes everywhere you go.",
"get_started": "Get started",
"github": "GitHub",
"dockerhub": "Docker Hub",
"screenshot_alt": "Screenshot of the Trilium Notes desktop application"
},
"organization_benefits": {
"title": "Organization",
"note_structure_title": "Note structure",
"note_structure_description": "Notes can be arranged hierarchically. There's no need for folders, since each note can contain sub-notes. A single note can be added in multiple places in the hierarchy.",
"attributes_title": "Note labels and relationships",
"attributes_description": "Use relations between notes or add labels for easy categorization. Use promoted attributes to enter structured information which can be used in tables, boards.",
"hoisting_title": "Workspaces and hoisting",
"hoisting_description": "Easily separate your personal and work notes by grouping them under a workspace, which focuses your note tree to only show a specific set of notes."
},
"productivity_benefits": {
"title": "Productivity and safety",
"revisions_title": "Note revisions",
"revisions_content": "Notes are periodically saved in the background and revisions can be used for review or to undo accidental changes. Revisions can also be created on-demand.",
"sync_title": "Synchronization",
"sync_content": "Use a self-hosted or cloud instance to easily synchronize your notes across multiple devices, and to access it from your mobile phone using a PWA.",
"protected_notes_title": "Protected notes",
"protected_notes_content": "Protect sensitive personal information by encrypting the notes and locking them behind a password-protected session.",
"jump_to_title": "Quick search and commands",
"jump_to_content": "Jump quickly to notes or UI commands across the hierarchy by searching for their title, with fuzzy matching to account for typos or slight differences.",
"search_title": "Powerful search",
"search_content": "Or search for text inside notes and narrow down the search by filtering by the parent note, or by depth.",
"web_clipper_title": "Web clipper",
"web_clipper_content": "Grab web pages (or screenshots) and place them directly into Trilium using the web clipper browser extension."
},
"note_types": {
"text_title": "Text notes",
"text_description": "The notes are edited using a visual (WYSIWYG) editor, with support for tables, images, math expressions, code blocks with syntax highlighting. Quickly format the text using Markdown-like syntax or using slash commands.",
"code_title": "Code notes",
"code_description": "Large samples of source code or scripts use a dedicated editor, with syntax highlighting for many programming languages and with various color themes.",
"file_title": "File notes",
"file_description": "Embed multimedia files such as PDFs, images, videos with an in-application preview.",
"canvas_title": "Canvas",
"canvas_description": "Arrange shapes, images and text across an infinite canvas, using the same technology behind excalidraw.com. Ideal for diagrams, sketches and visual planning.",
"mermaid_title": "Mermaid diagrams",
"mermaid_description": "Create diagrams such as flowcharts, class & sequence diagrams, Gantt charts and many more, using the Mermaid syntax.",
"mindmap_title": "Mindmap",
"mindmap_description": "Organize your thoughts visually or do a brainstorming session.",
"others_prefix": "and others: ",
"others_separator": ", ",
"others_note_map": "note map",
"others_relation_map": "relation map",
"others_saved_searches": "saved searches",
"others_render_note": "render note",
"others_webview": "web views",
"others_list": "and others: <0>note map</0>, <1>relation map</1>, <2>saved searches</2>, <3>render note</3>, and <4>web views</4>."
},
"extensibility_benefits": {
"title": "Sharing & extensibility",
"import_export_title": "Import/export",
"import_export_description": "Easily interact with other applications using Markdown, ENEX, OML formats.",
"share_title": "Share notes on the web",
"share_description": "If you have a server, it can be used to share a subset of your notes with other people.",
"scripting_title": "Advanced scripting",
"scripting_description": "Build your own integrations within Trilium with custom widgets, or server-side logic.",
"api_title": "REST API",
"api_description": "Interact with Trilium programatically using its builtin REST API."
},
"collections": {
"calendar_title": "Calendar",
"calendar_description": "Organize your personal or professional events using a calendar, with support for all-day and multi-day events. See your events at a glance with the week, month and year views. Easy interaction to add or drag events.",
"table_title": "Table",
"table_description": "Display and edit information about notes in a tabular structure, with various column types such as text, number, check boxes, date & time, links and colors and support for relations. Optionally, display the notes within a tree hierarchy inside the table.",
"board_title": "Board",
"board_description": "Organize your tasks or project status into a Kanban board with an easy way to create new items and columns and simply changing their status by dragging across the board.",
"geomap_title": "Geomap",
"geomap_description": "Plan your vacations or mark your points of interest directly on a geographical map using customizable markers. Display recorded GPX tracks to track itineraries."
},
"faq": {
"title": "Frequently Asked Questions",
"mobile_question": "Is there a mobile application?",
"mobile_answer": "Currently there is no official mobile application. However, if you have a server instance you can access it using a web browser and even install it as a PWA. For Android, there is an unofficial application called TriliumDroid that even works offline (same as a desktop client).",
"database_question": "Where is the data stored?",
"database_answer": "All your notes will be stored in an SQLite database in an application folder. The reasoning why Trilium uses a database instead of plain text files is both performance and some features would be much more difficult to implement such as clones (same note in multiple places in the tree). To find the application folder, simply go to the About window.",
"server_question": "Do I need a server to use Trilium?",
"server_answer": "No, the server allows access via a web browser and manages the synchronization if you have multiple devices. To get started, it's enough to download the desktop application and start using it.",
"scaling_question": "How well does the application scale with a large amount of notes?",
"scaling_answer": "Depending on usage, the application should be able to handle at least 100,000 notes without an issue. Do note that the sync process can sometimes fail if uploading many large files (1 GB per file) since Trilium is meant more as a knowledge base application rather than a file store (like NextCloud, for example).",
"network_share_question": "Can I share my database over a network drive?",
"network_share_answer": "No, it's generally not a good idea to share a SQLite database over a network drive. Although sometimes it might work, there are chances that the database will get corrupted due to imperfect file locks over a network.",
"security_question": "How is my data protected?",
"security_answer": "By default, notes are not encrypted and can be read directly from the database. Once a note is marked as encrypted, the note is encrypted using AES-128-CBC."
},
"final_cta": {
"title": "Ready to get started with Trilium Notes?",
"description": "Build your personal knowledge base with powerful features and full privacy.",
"get_started": "Get started"
},
"components": {
"link_learn_more": "Learn more...",
"list_with_screenshot_alt": "Screenshot of the feature being selected"
},
"download_now": {
"text": "Download now ",
"platform_big": "v{{version}} for {{platform}}",
"platform_small": "for {{platform}}",
"linux_big": "v{{version}} for Linux",
"linux_small": "for Linux",
"more_platforms": "More platforms & server setup"
},
"footer": {
"copyright_and_the": " and the ",
"copyright_community": "community"
},
"social_buttons": {
"github": "GitHub",
"github_discussions": "GitHub Discussions",
"matrix": "Matrix",
"reddit": "Reddit"
},
"support_us": {
"title": "Support us",
"financial_donations_title": "Financial donations",
"financial_donations_description": "Trilium is built and maintained with <Link>hundreds of hours of work</Link>. Your support keeps it open-source, improves features, and covers costs such as hosting.",
"financial_donations_cta": "Consider supporting the main developer (<Link>eliandoran</Link>) of the application via:",
"github_sponsors": "GitHub Sponsors",
"paypal": "PayPal",
"buy_me_a_coffee": "Buy Me A Coffee"
},
"contribute": {
"title": "Other ways to contribute",
"way_translate": "Translate the application into your native language via <Link>Weblate</Link>.",
"way_community": "Interact with the community on <Discussions>GitHub Discussions</Discussions> or on <Matrix>Matrix</Matrix>.",
"way_reports": "Report bugs via <Link>GitHub issues</Link>.",
"way_document": "Improve the documentation by informing us on gaps in the documentation or contributing guides, FAQs or tutorials.",
"way_market": "Spread the word: Share Trilium Notes with friends, or on blogs and social media."
},
"404": {
"title": "404: Not Found",
"description": "The page you were looking for could not be found. Maybe it was deleted or the URL is incorrect."
},
"download_helper_desktop_windows": {
"title_x64": "Windows 64-bit",
"title_arm64": "Windows on ARM",
"description_x64": "Compatible with Intel or AMD devices running Windows 10 and 11.",
"description_arm64": "Compatible with ARM devices (e.g. with Qualcomm Snapdragon).",
"quick_start": "To install via Winget:",
"download_exe": "Download Installer (.exe)",
"download_zip": "Portable (.zip)",
"download_scoop": "Scoop"
},
"download_helper_desktop_linux": {
"title_x64": "Linux 64-bit",
"title_arm64": "Linux on ARM",
"description_x64": "For most Linux distributions, compatible with x86_64 architecture.",
"description_arm64": "For ARM-based Linux distributions, compatible with aarch64 architecture.",
"quick_start": "Select an appropriate package format, depending on your distribution:",
"download_deb": ".deb",
"download_rpm": ".rpm",
"download_flatpak": ".flatpak",
"download_zip": "Portable (.zip)",
"download_nixpkgs": "nixpkgs",
"download_aur": "AUR"
},
"download_helper_desktop_macos": {
"title_x64": "macOS for Intel",
"title_arm64": "macOS for Apple Silicon",
"description_x64": "For Intel-based Macs running macOS Big Sur or later.",
"description_arm64": "For Apple Silicon Macs such as those with M1 and M2 chips.",
"quick_start": "To install via Homebrew:",
"download_dmg": "Download Installer (.dmg)",
"download_homebrew_cask": "Homebrew Cask",
"download_zip": "Portable (.zip)"
},
"download_helper_server_docker": {
"title": "Self-hosted using Docker",
"description": "Easily deploy on Windows, Linux or macOS using a Docker container.",
"download_dockerhub": "Docker Hub",
"download_ghcr": "ghcr.io"
},
"download_helper_server_linux": {
"title": "Self-hosted on Linux",
"description": "Deploy Trilium Notes on your own server or VPS, compatible with most distributions.",
"download_tar_x64": "x64 (.tar.xz)",
"download_tar_arm64": "ARM (.tar.xz)",
"download_nixos": "NixOS module"
},
"download_helper_server_hosted": {
"title": "Paid hosting",
"description": "Trilium Notes hosted on PikaPods, a paid service for easy access and management. Not directly affiliated with the Trilium team.",
"download_pikapod": "Set up on PikaPods",
"download_triliumcc": "Alternatively see trilium.cc"
}
}

View File

@ -6,7 +6,7 @@ interface LinkProps {
className?: string;
href?: string;
openExternally?: boolean;
children: ComponentChildren;
children?: ComponentChildren;
title?: string;
onClick?: (e: MouseEvent) => void;
}

View File

@ -1,6 +1,7 @@
import { ComponentChildren, HTMLAttributes } from "preact";
import { Link } from "./Button.js";
import Icon from "./Icon.js";
import { t } from "../i18n.js";
interface CardProps extends Omit<HTMLAttributes<HTMLDivElement>, "title"> {
title: ComponentChildren;
@ -28,7 +29,7 @@ export default function Card({ title, children, imageUrl, iconSvg, className, mo
{moreInfoUrl && (
<div className="more-info-container">
<Link href={moreInfoUrl} className="more-info" openExternally>Learn more...</Link>
<Link href={moreInfoUrl} className="more-info" openExternally>{t("components.link_learn_more")}</Link>
</div>
)}
</div>

View File

@ -4,6 +4,7 @@ import Button from "./Button.js";
import downloadIcon from "../assets/boxicons/bx-arrow-in-down-square-half.svg?raw";
import packageJson from "../../../../package.json" with { type: "json" };
import { useEffect, useState } from "preact/hooks";
import { t } from "../i18n.js";
interface DownloadButtonProps {
big?: boolean;
@ -24,10 +25,10 @@ export default function DownloadButton({ big }: DownloadButtonProps) {
href={recommendedDownload.url}
iconSvg={downloadIcon}
text={<>
Download now{" "}
{t("download_now.text")}
{big
? <span class="platform">v{packageJson.version} for {recommendedDownload.name}</span>
: <span class="platform">for {recommendedDownload.name}</span>
? <span class="platform">{t("download_now.platform_big", { version: packageJson.version, platform: recommendedDownload.name })}</span>
: <span class="platform">{t("download_now.platform_small", { platform: recommendedDownload.name })}</span>
}
</>}
/>
@ -37,17 +38,17 @@ export default function DownloadButton({ big }: DownloadButtonProps) {
href="/get-started/"
iconSvg={downloadIcon}
text={<>
Download now{" "}
{t("download_now.text")}
{big
? <span class="platform">v{packageJson.version} for Linux</span>
: <span class="platform">for Linux</span>
? <span class="platform">{t("download_now.linux_big", { version: packageJson.version })}</span>
: <span class="platform">{t("download_now.linux_small")}</span>
}
</>}
/>
)}
{big && (
<a class="more-download-options desktop-only" href="./get-started/">More platforms & server setup</a>
<a class="more-download-options desktop-only" href="./get-started/">{t("download_now.more_platforms")}</a>
)}
</>
)

View File

@ -5,13 +5,14 @@ import githubDiscussionsIcon from "../assets/boxicons/bx-discussion.svg?raw";
import matrixIcon from "../assets/boxicons/bx-message-dots.svg?raw";
import redditIcon from "../assets/boxicons/bx-reddit.svg?raw";
import { Link } from "./Button.js";
import { t } from "../i18n";
export default function Footer() {
return (
<footer>
<div class="content-wrapper">
<div class="footer-text">
© 2024-2025 <Link href="https://github.com/eliandoran" openExternally>Elian Doran</Link> and the <Link href="https://github.com/TriliumNext/Trilium/graphs/contributors" openExternally>community</Link>.<br />
© 2024-2025 <Link href="https://github.com/eliandoran" openExternally>Elian Doran</Link>{t("footer.copyright_and_the")}<Link href="https://github.com/TriliumNext/Trilium/graphs/contributors" openExternally>{t("footer.copyright_community")}</Link>.<br />
© 2017-2024 <Link href="https://github.com/zadam" openExternally>zadam</Link>.
</div>
@ -25,28 +26,28 @@ export function SocialButtons({ className, withText }: { className?: string, wit
return (
<div className={`social-buttons ${className}`}>
<SocialButton
name="GitHub"
name={t("social_buttons.github")}
iconSvg={githubIcon}
url="https://github.com/TriliumNext/Trilium"
withText={withText}
/>
<SocialButton
name="GitHub Discussions"
name={t("social_buttons.github_discussions")}
iconSvg={githubDiscussionsIcon}
url="https://github.com/orgs/TriliumNext/discussions"
withText={withText}
/>
<SocialButton
name="Matrix"
name={t("social_buttons.matrix")}
iconSvg={matrixIcon}
url="https://matrix.to/#/#triliumnext:matrix.org"
withText={withText}
/>
<SocialButton
name="Reddit"
name={t("social_buttons.reddit")}
iconSvg={redditIcon}
url="https://www.reddit.com/r/Trilium/"
withText={withText}
@ -63,7 +64,7 @@ export function SocialButton({ name, iconSvg, url, withText, counter }: { name:
title={!withText ? name : undefined}
>
<Icon svg={iconSvg} />
{counter && <span class="counter">{counter}</span>}
{counter && <span class="counter">{counter}</span>}
{withText && name}
</Link>
)

View File

@ -1,4 +1,5 @@
import rootPackageJson from '../../../package.json' with { type: "json" };
import { t } from './i18n';
export type App = "desktop" | "server";
@ -37,139 +38,139 @@ export const downloadMatrix: DownloadMatrix = {
desktop: {
windows: {
title: {
x64: "Windows 64-bit",
arm64: "Windows on ARM"
x64: t("download_helper_desktop_windows.title_x64"),
arm64: t("download_helper_desktop_windows.title_arm64")
},
description: {
x64: "Compatible with Intel or AMD devices running Windows 10 and 11.",
arm64: "Compatible with ARM devices (e.g. with Qualcomm Snapdragon).",
x64: t("download_helper_desktop_windows.description_x64"),
arm64: t("download_helper_desktop_windows.description_arm64"),
},
quickStartTitle: "To install via Winget:",
quickStartTitle: t("download_helper_desktop_windows.quick_start"),
quickStartCode: "winget install TriliumNext.Notes",
downloads: {
exe: {
recommended: true,
name: "Download Installer (.exe)"
name: t("download_helper_desktop_windows.download_exe")
},
zip: {
name: "Portable (.zip)"
name: t("download_helper_desktop_windows.download_zip")
},
scoop: {
name: "Scoop",
name: t("download_helper_desktop_windows.download_scoop"),
url: "https://scoop.sh/#/apps?q=trilium&id=7c08bc3c105b9ee5c00dd4245efdea0f091b8a5c"
}
}
},
linux: {
title: {
x64: "Linux 64-bit",
arm64: "Linux on ARM"
x64: t("download_helper_desktop_linux.title_x64"),
arm64: t("download_helper_desktop_linux.title_arm64")
},
description: {
x64: "For most Linux distributions, compatible with x86_64 architecture.",
arm64: "For ARM-based Linux distributions, compatible with aarch64 architecture.",
x64: t("download_helper_desktop_linux.description_x64"),
arm64: t("download_helper_desktop_linux.description_arm64"),
},
quickStartTitle: "Select an appropriate package format, depending on your distribution:",
quickStartTitle: t("download_helper_desktop_linux.quick_start"),
downloads: {
deb: {
recommended: true,
name: ".deb"
name: t("download_helper_desktop_linux.download_deb")
},
rpm: {
recommended: true,
name: ".rpm"
name: t("download_helper_desktop_linux.download_rpm")
},
flatpak: {
name: ".flatpak"
name: t("download_helper_desktop_linux.download_flatpak")
},
zip: {
name: "Portable (.zip)"
name: t("download_helper_desktop_linux.download_zip")
},
nixpkgs: {
name: "nixpkgs",
name: t("download_helper_desktop_linux.download_nixpkgs"),
url: "https://search.nixos.org/packages?query=trilium-next"
},
aur: {
name: "AUR",
name: t("download_helper_desktop_linux.download_aur"),
url: "https://aur.archlinux.org/packages/triliumnext-bin"
}
}
},
macos: {
title: {
x64: "macOS for Intel",
arm64: "macOS for Apple Silicon"
x64: t("download_helper_desktop_macos.title_x64"),
arm64: t("download_helper_desktop_macos.title_arm64")
},
description: {
x64: "For Intel-based Macs running macOS Big Sur or later.",
arm64: "For Apple Silicon Macs such as those with M1 and M2 chips.",
x64: t("download_helper_desktop_macos.description_x64"),
arm64: t("download_helper_desktop_macos.description_arm64"),
},
quickStartTitle: "To install via Homebrew:",
quickStartTitle: t("download_helper_desktop_macos.quick_start"),
quickStartCode: "brew install --cask trilium-notes",
downloads: {
dmg: {
recommended: true,
name: "Download Installer (.dmg)"
name: t("download_helper_desktop_macos.download_dmg")
},
homebrew: {
name: "Homebrew Cask",
name: t("download_helper_desktop_macos.download_homebrew_cask"),
url: "https://formulae.brew.sh/cask/trilium-notes#default"
},
zip: {
name: "Portable (.zip)"
name: t("download_helper_desktop_macos.download_zip")
}
}
}
},
server: {
docker: {
title: "Self-hosted using Docker",
description: "Easily deploy on Windows, Linux or macOS using a Docker container.",
title: t("download_helper_server_docker.title"),
description: t("download_helper_server_docker.description"),
helpUrl: "https://docs.triliumnotes.org/User%20Guide/User%20Guide/Installation%20%26%20Setup/Server%20Installation/1.%20Installing%20the%20server/Using%20Docker.html",
quickStartCode: "docker pull triliumnext/trilium\ndocker run -p 8080:8080 -d ./data:/home/node/trilium-data triliumnext/trilium",
downloads: {
dockerhub: {
name: "Docker Hub",
name: t("download_helper_server_docker.download_dockerhub"),
url: "https://hub.docker.com/r/triliumnext/trilium"
},
ghcr: {
name: "ghcr.io",
name: t("download_helper_server_docker.download_ghcr"),
url: "https://github.com/TriliumNext/Trilium/pkgs/container/trilium"
}
}
},
linux: {
title: "Self-hosted on Linux",
description: "Deploy Trilium Notes on your own server or VPS, compatible with most distributions.",
title: t("download_helper_server_linux.title"),
description: t("download_helper_server_linux.description"),
helpUrl: "https://docs.triliumnotes.org/User%20Guide/User%20Guide/Installation%20%26%20Setup/Server%20Installation/1.%20Installing%20the%20server/Packaged%20version%20for%20Linux.html",
downloads: {
tarX64: {
recommended: true,
name: "x64 (.tar.xz)",
name: t("download_helper_server_linux.download_tar_x64"),
url: `https://github.com/TriliumNext/Trilium/releases/download/v${version}/TriliumNotes-Server-v${version}-linux-x64.tar.xz`,
},
tarArm64: {
recommended: true,
name: "ARM (.tar.xz)",
name: t("download_helper_server_linux.download_tar_arm64"),
url: `https://github.com/TriliumNext/Trilium/releases/download/v${version}/TriliumNotes-Server-v${version}-linux-arm64.tar.xz`
},
nixos: {
name: "NixOS module",
name: t("download_helper_server_linux.download_nixos"),
url: "https://docs.triliumnotes.org/User%20Guide/User%20Guide/Installation%20&%20Setup/Server%20Installation/1.%20Installing%20the%20server/On%20NixOS"
}
}
},
pikapod: {
title: "Paid hosting",
description: "Trilium Notes hosted on PikaPods, a paid service for easy access and management. Not directly affiliated with the Trilium team.",
title: t("download_helper_server_hosted.title"),
description: t("download_helper_server_hosted.description"),
downloads: {
pikapod: {
recommended: true,
name: "Set up on PikaPods",
name: t("download_helper_server_hosted.download_pikapod"),
url: "https://www.pikapods.com/pods?run=trilium-next"
},
triliumcc: {
name: "Alternatively see trilium.cc",
name: t("download_helper_server_hosted.download_triliumcc"),
url: "https://trilium.cc/"
}
}

19
apps/website/src/i18n.ts Normal file
View File

@ -0,0 +1,19 @@
import { default as i18next } from "i18next";
import HttpApi from 'i18next-http-backend';
import { initReactI18next } from "react-i18next";
i18next
.use(HttpApi)
.use(initReactI18next);
await i18next.init({
debug: true,
lng: "en",
fallbackLng: "en",
backend: {
loadPath: "/translations/{{lng}}/{{ns}}.json",
},
returnEmptyString: false
});
export const t = i18next.t;

View File

@ -8,6 +8,7 @@ import Icon from "../../components/Icon.js";
import helpIcon from "../../assets/boxicons/bx-help-circle.svg?raw";
import "./get-started.css";
import packageJson from "../../../../../package.json" with { type: "json" };
import { t } from "../../i18n.js";
export default function DownloadPage() {
const [ currentArch, setCurrentArch ] = useState<Architecture>("x64");
@ -18,13 +19,13 @@ export default function DownloadPage() {
setUserPlatform(getPlatform() ?? "windows");
}, []);
usePageTitle("Get started");
usePageTitle(t("get-started.title"));
return (
<>
<Section title={`Download the desktop application (v${packageJson.version})`} className="fill accented download-desktop">
<Section title={t("get-started.desktop_title", { version: packageJson.version })} className="fill accented download-desktop">
<div className="architecture-switch">
<span>Architecture:</span>
<span>{t("get-started.architecture")}</span>
<div class="toggle-wrapper">
{(["x64", "arm64"] as const).map(arch => (
@ -45,11 +46,11 @@ export default function DownloadPage() {
</div>
<div class="download-footer">
<Link href="https://github.com/TriliumNext/Trilium/releases/" openExternally>See older releases</Link>
<Link href="https://github.com/TriliumNext/Trilium/releases/" openExternally>{t("get-started.older_releases")}</Link>
</div>
</Section>
<Section title="Set up a server for access on multiple devices">
<Section title={t("get-started.server_title")}>
<div className="grid-2-cols download-server">
{Object.entries(downloadMatrix.server).map(entry => (
<DownloadCard app="server" arch={currentArch} entry={entry} />

View File

@ -31,6 +31,8 @@ import boardIcon from "../../assets/boxicons/bx-columns-3.svg?raw";
import geomapIcon from "../../assets/boxicons/bx-map.svg?raw";
import { getPlatform } from '../../download-helper.js';
import { useEffect, useState } from 'preact/hooks';
import { t } from '../../i18n.js';
import { Trans } from 'react-i18next';
export function Home() {
usePageTitle("");
@ -72,22 +74,22 @@ function HeroSection() {
return (
<Section className="hero-section">
<div class="title-section">
<h1>Organize your thoughts. Build your personal knowledge base.</h1>
<p>Trilium is an open-source solution for note-taking and organizing a personal knowledge base. Use it locally on your desktop, or sync it with your self-hosted server to keep your notes everywhere you go.</p>
<h1>{t("hero_section.title")}</h1>
<p>{t("hero_section.subtitle")}</p>
<div className="download-wrapper">
<DownloadButton big />
<Button href="./get-started/" className="mobile-only" text="Get started" />
<Button href="./get-started/" className="mobile-only" text={t("hero_section.get_started")} />
<div className="additional-options">
<Button iconSvg={gitHubIcon} outline text="GitHub" href="https://github.com/TriliumNext/Trilium/" openExternally />
<Button iconSvg={dockerIcon} outline text="Docker Hub" href="https://hub.docker.com/r/triliumnext/trilium" openExternally />
<Button iconSvg={gitHubIcon} outline text={t("hero_section.github")} href="https://github.com/TriliumNext/Trilium/" openExternally />
<Button iconSvg={dockerIcon} outline text={t("hero_section.dockerhub")} href="https://hub.docker.com/r/triliumnext/trilium" openExternally />
</div>
</div>
</div>
<div className="screenshot-container">
{screenshotUrl && <img class="screenshot" src={screenshotUrl} alt="Screenshot of the Trilium Notes desktop application" />}
{screenshotUrl && <img class="screenshot" src={screenshotUrl} alt={t("hero_section.screenshot_alt")} />}
</div>
</Section>
)
@ -96,11 +98,11 @@ function HeroSection() {
function OrganizationBenefitsSection() {
return (
<>
<Section className="benefits" title="Organization">
<Section className="benefits" title={t("organization_benefits.title")}>
<div className="benefits-container grid-3-cols">
<Card iconSvg={noteStructureIcon} title="Note structure" moreInfoUrl="https://docs.triliumnotes.org/User%20Guide/User%20Guide/Basic%20Concepts%20and%20Features/Notes/index.html">Notes can be arranged hierarchically. There's no need for folders, since each note can contain sub-notes. A single note can be added in multiple places in the hierarchy.</Card>
<Card iconSvg={attributesIcon} title="Note labels and relationships" moreInfoUrl="https://docs.triliumnotes.org/User Guide/User Guide/Advanced Usage/Attributes/index.html">Use <em>relations</em> between notes or add <em>labels</em> for easy categorization. Use promoted attributes to enter structured information which can be used in tables, boards.</Card>
<Card iconSvg={hoistingIcon} title="Workspaces and hoisting" moreInfoUrl="https://docs.triliumnotes.org/User%20Guide/User%20Guide/Basic%20Concepts%20and%20Features/Navigation/Note%20Hoisting.html">Easily separate your personal and work notes by grouping them under a workspace, which focuses your note tree to only show a specific set of notes.</Card>
<Card iconSvg={noteStructureIcon} title={t("organization_benefits.note_structure_title")} moreInfoUrl="https://docs.triliumnotes.org/User%20Guide/User%20Guide/Basic%20Concepts%20and%20Features/Notes/index.html">{t("organization_benefits.note_structure_description")}</Card>
<Card iconSvg={attributesIcon} title={t("organization_benefits.attributes_title")} moreInfoUrl="https://docs.triliumnotes.org/User Guide/User Guide/Advanced Usage/Attributes/index.html">{t("organization_benefits.attributes_description")}</Card>
<Card iconSvg={hoistingIcon} title={t("organization_benefits.hoisting_title")} moreInfoUrl="https://docs.triliumnotes.org/User%20Guide/User%20Guide/Basic%20Concepts%20and%20Features/Navigation/Note%20Hoisting.html">{t("organization_benefits.hoisting_description")}</Card>
</div>
</Section>
</>
@ -110,14 +112,14 @@ function OrganizationBenefitsSection() {
function ProductivityBenefitsSection() {
return (
<>
<Section className="benefits accented" title="Productivity and safety">
<Section className="benefits accented" title={t("productivity_benefits.title")}>
<div className="benefits-container grid-3-cols">
<Card iconSvg={revisionsIcon} title="Note revisions" moreInfoUrl="https://docs.triliumnotes.org/User%20Guide/User%20Guide/Basic%20Concepts%20and%20Features/Notes/Note%20Revisions.html">Notes are periodically saved in the background and revisions can be used for review or to undo accidental changes. Revisions can also be created on-demand.</Card>
<Card iconSvg={syncIcon} title="Synchronization" moreInfoUrl="https://docs.triliumnotes.org/User%20Guide/User%20Guide/Installation%20%26%20Setup/Synchronization.html">Use a self-hosted or cloud instance to easily synchronize your notes across multiple devices, and to access it from your mobile phone using a PWA.</Card>
<Card iconSvg={protectedNotesIcon} title="Protected notes" moreInfoUrl="https://docs.triliumnotes.org/User%20Guide/User%20Guide/Basic%20Concepts%20and%20Features/Notes/Protected%20Notes.html">Protect sensitive personal information by encrypting the notes and locking them behind a password-protected session.</Card>
<Card iconSvg={jumpToIcon} title="Quick search and commands" moreInfoUrl="https://docs.triliumnotes.org/User%20Guide/User%20Guide/Basic%20Concepts%20and%20Features/Navigation/Jump%20to.html">Jump quickly to notes or UI commands across the hierarchy by searching for their title, with fuzzy matching to account for typos or slight differences.</Card>
<Card iconSvg={searchIcon} title="Powerful search" moreInfoUrl="https://docs.triliumnotes.org/User%20Guide/User%20Guide/Basic%20Concepts%20and%20Features/Navigation/Search.html">Or search for text inside notes and narrow down the search by filtering by the parent note, or by depth.</Card>
<Card iconSvg={webClipperIcon} title="Web clipper" moreInfoUrl="https://docs.triliumnotes.org/User%20Guide/User%20Guide/Installation%20%26%20Setup/Web%20Clipper.html">Grab web pages (or screenshots) and place them directly into Trilium using the web clipper browser extension.</Card>
<Card iconSvg={revisionsIcon} title={t("productivity_benefits.revisions_title")} moreInfoUrl="https://docs.triliumnotes.org/User%20Guide/User%20Guide/Basic%20Concepts%20and%20Features/Notes/Note%20Revisions.html">{t("productivity_benefits.revisions_content")}</Card>
<Card iconSvg={syncIcon} title={t("productivity_benefits.sync_title")} moreInfoUrl="https://docs.triliumnotes.org/User%20Guide/User%20Guide/Installation%20%26%20Setup/Synchronization.html">{t("productivity_benefits.sync_content")}</Card>
<Card iconSvg={protectedNotesIcon} title={t("productivity_benefits.protected_notes_title")} moreInfoUrl="https://docs.triliumnotes.org/User%20Guide/User%20Guide/Basic%20Concepts%20and%20Features/Notes/Protected%20Notes.html">{t("productivity_benefits.protected_notes_content")}</Card>
<Card iconSvg={jumpToIcon} title={t("productivity_benefits.jump_to_title")} moreInfoUrl="https://docs.triliumnotes.org/User%20Guide/User%20Guide/Basic%20Concepts%20and%20Features/Navigation/Jump%20to.html">{t("productivity_benefits.jump_to_content")}</Card>
<Card iconSvg={searchIcon} title={t("productivity_benefits.search_title")} moreInfoUrl="https://docs.triliumnotes.org/User%20Guide/User%20Guide/Basic%20Concepts%20and%20Features/Navigation/Search.html">{t("productivity_benefits.search_content")}</Card>
<Card iconSvg={webClipperIcon} title={t("productivity_benefits.web_clipper_title")} moreInfoUrl="https://docs.triliumnotes.org/User%20Guide/User%20Guide/Installation%20%26%20Setup/Web%20Clipper.html">{t("productivity_benefits.web_clipper_content")}</Card>
</div>
</Section>
</>
@ -129,55 +131,59 @@ function NoteTypesSection() {
<Section className="note-types" title="Multiple ways to represent your information">
<ListWithScreenshot horizontal items={[
{
title: "Text notes",
title: t("note_types.text_title"),
imageUrl: "/type_text.webp",
iconSvg: textNoteIcon,
moreInfo: "https://docs.triliumnotes.org/User%20Guide/User%20Guide/Note%20Types/Text/index.html",
description: "The notes are edited using a visual (WYSIWYG) editor, with support for tables, images, math expressions, code blocks with syntax highlighting. Quickly format the text using Markdown-like syntax or using slash commands."
description: t("note_types.text_description")
},
{
title: "Code notes",
title: t("note_types.code_title"),
imageUrl: "/type_code.webp",
iconSvg: codeIcon,
moreInfo: "https://docs.triliumnotes.org/User%20Guide/User%20Guide/Note%20Types/Code.html",
description: "Large samples of source code or scripts use a dedicated editor, with syntax highlighting for many programming languages and with various color themes."
description: t("note_types.code_description")
},
{
title: "File notes",
title: t("note_types.file_title"),
imageUrl: "/type_file.webp",
iconSvg: fileIcon,
moreInfo: "https://docs.triliumnotes.org/User%20Guide/User%20Guide/Note%20Types/File.html",
description: "Embed multimedia files such as PDFs, images, videos with an in-application preview."
description: t("note_types.file_description")
},
{
title: "Canvas",
title: t("note_types.canvas_title"),
imageUrl: "/type_canvas.webp",
iconSvg: canvasIcon,
moreInfo: "https://docs.triliumnotes.org/User%20Guide/User%20Guide/Note%20Types/Canvas.html",
description: "Arrange shapes, images and text across an infinite canvas, using the same technology behind excalidraw.com. Ideal for diagrams, sketches and visual planning."
description: t("note_types.canvas_description")
},
{
title: "Mermaid diagrams",
title: t("note_types.mermaid_title"),
imageUrl: "/type_mermaid.webp",
iconSvg: mermaidIcon,
moreInfo: "https://docs.triliumnotes.org/User%20Guide/User%20Guide/Note%20Types/Mermaid%20Diagrams/index.html",
description: "Create diagrams such as flowcharts, class & sequence diagrams, Gantt charts and many more, using the Mermaid syntax."
description: t("note_types.mermaid_description")
},
{
title: "Mindmap",
title: t("note_types.mindmap_title"),
imageUrl: "/type_mindmap.webp",
iconSvg: mindmapIcon,
moreInfo: "https://docs.triliumnotes.org/User%20Guide/User%20Guide/Note%20Types/Mind%20Map.html",
description: "Organize your thoughts visually or do a brainstorming session."
description: t("note_types.mindmap_description")
}
]} />
<p>
and others:{" "}
<Link href="https://docs.triliumnotes.org/User%20Guide/User%20Guide/Note%20Types/Note%20Map.html" openExternally>note map</Link>,{" "}
<Link href="https://docs.triliumnotes.org/User%20Guide/User%20Guide/Note%20Types/Relation%20Map.html" openExternally>relation map</Link>,{" "}
<Link href="https://docs.triliumnotes.org/User%20Guide/User%20Guide/Note%20Types/Saved%20Search.html" openExternally>saved searches</Link>,{" "}
<Link href="https://docs.triliumnotes.org/User%20Guide/User%20Guide/Note%20Types/Render%20Note.html" openExternally>render note</Link>,{" "}
<Link href="https://docs.triliumnotes.org/User%20Guide/User%20Guide/Note%20Types/Web%20View.html" openExternally>web views</Link>.
<Trans
i18nKey="note_types.others_list"
components={[
<Link href="https://docs.triliumnotes.org/User%20Guide/User%20Guide/Note%20Types/Note%20Map.html" openExternally />,
<Link href="https://docs.triliumnotes.org/User%20Guide/User%20Guide/Note%20Types/Relation%20Map.html" openExternally />,
<Link href="https://docs.triliumnotes.org/User%20Guide/User%20Guide/Note%20Types/Saved%20Search.html" openExternally />,
<Link href="https://docs.triliumnotes.org/User%20Guide/User%20Guide/Note%20Types/Render%20Note.html" openExternally />,
<Link href="https://docs.triliumnotes.org/User%20Guide/User%20Guide/Note%20Types/Web%20View.html" openExternally />
]}
/>
</p>
</Section>
);
@ -186,12 +192,12 @@ function NoteTypesSection() {
function ExtensibilityBenefitsSection() {
return (
<>
<Section className="benefits accented" title="Sharing & extensibility">
<Section className="benefits accented" title={t("extensibility_benefits.title")}>
<div className="benefits-container grid-4-cols">
<Card iconSvg={importExportIcon} title="Import/export" moreInfoUrl="https://docs.triliumnotes.org/User%20Guide/User%20Guide/Basic%20Concepts%20and%20Features/Import%20%26%20Export/Markdown/index.html">Easily interact with other applications using Markdown, ENEX, OML formats.</Card>
<Card iconSvg={shareIcon} title="Share notes on the web" moreInfoUrl="https://docs.triliumnotes.org/User%20Guide/User%20Guide/Advanced%20Usage/Sharing/Serving%20directly%20the%20content%20o.html">If you have a server, it can be used to share a subset of your notes with other people.</Card>
<Card iconSvg={codeIcon} title="Advanced scripting" moreInfoUrl="https://docs.triliumnotes.org/User%20Guide/User%20Guide/Scripting/Custom%20Widgets/index.html">Build your own integrations within Trilium with custom widgets, or server-side logic.</Card>
<Card iconSvg={restApiIcon} title="REST API" moreInfoUrl="https://docs.triliumnotes.org/User%20Guide/User%20Guide/Advanced%20Usage/ETAPI%20%28REST%20API%29/index.html">Interact with Trilium programatically using its builtin REST API.</Card>
<Card iconSvg={importExportIcon} title={t("extensibility_benefits.import_export_title")} moreInfoUrl="https://docs.triliumnotes.org/User%20Guide/User%20Guide/Basic%20Concepts%20and%20Features/Import%20%26%20Export/Markdown/index.html">{t("extensibility_benefits.import_export_description")}</Card>
<Card iconSvg={shareIcon} title={t("extensibility_benefits.share_title")} moreInfoUrl="https://docs.triliumnotes.org/User%20Guide/User%20Guide/Advanced%20Usage/Sharing/Serving%20directly%20the%20content%20o.html">{t("extensibility_benefits.share_description")}</Card>
<Card iconSvg={codeIcon} title={t("extensibility_benefits.scripting_title")} moreInfoUrl="https://docs.triliumnotes.org/User%20Guide/User%20Guide/Scripting/Custom%20Widgets/index.html">{t("extensibility_benefits.scripting_description")}</Card>
<Card iconSvg={restApiIcon} title={t("extensibility_benefits.api_title")} moreInfoUrl="https://docs.triliumnotes.org/User%20Guide/User%20Guide/Advanced%20Usage/ETAPI%20%28REST%20API%29/index.html">{t("extensibility_benefits.api_description")}</Card>
</div>
</Section>
</>
@ -203,31 +209,32 @@ function CollectionsSection() {
<Section className="collections" title="Collections">
<ListWithScreenshot items={[
{
title: "Calendar",
title: t("collections.calendar_title"),
imageUrl: "/collection_calendar.webp",
iconSvg: calendarIcon,
moreInfo: "https://docs.triliumnotes.org/User%20Guide/User%20Guide/Note%20Types/Collections/Calendar%20View.html",
description: "Organize your personal or professional events using a calendar, with support for all-day and multi-day events. See your events at a glance with the week, month and year views. Easy interaction to add or drag events."
description: t("collections.calendar_description")
},
{
title: "Table",
title: t("collections.table_title"),
iconSvg: tableIcon,
imageUrl: "/collection_table.webp",
moreInfo: "https://docs.triliumnotes.org/User%20Guide/User%20Guide/Note%20Types/Collections/Table%20View.html",
description: "Display and edit information about notes in a tabular structure, with various column types such as text, number, check boxes, date & time, links and colors and support for relations. Optionally, display the notes within a tree hierarchy inside the table." },
description: t("collections.table_description")
},
{
title: "Board",
title: t("collections.board_title"),
iconSvg: boardIcon,
imageUrl: "/collection_board.webp",
moreInfo: "https://docs.triliumnotes.org/User%20Guide/User%20Guide/Note%20Types/Collections/Board%20View.html",
description: "Organize your tasks or project status into a Kanban board with an easy way to create new items and columns and simply changing their status by dragging across the board."
description: t("collections.board_description")
},
{
title: "Geomap",
title: t("collections.geomap_title"),
iconSvg: geomapIcon,
imageUrl: "/collection_geomap.webp",
moreInfo: "https://docs.triliumnotes.org/User%20Guide/User%20Guide/Note%20Types/Collections/Geo%20Map%20View.html",
description: "Plan your vacations or mark your points of interest directly on a geographical map using customizable markers. Display recorded GPX tracks to track itineraries."
description: t("collections.geomap_description")
}
]} />
</Section>
@ -262,7 +269,7 @@ function ListWithScreenshot({ items, horizontal, cardExtra }: {
<div className="details">
{selectedItem && (
<>
<img src={selectedItem.imageUrl} alt="Screenshot of the feature being selected" loading="lazy" />
<img src={selectedItem.imageUrl} alt={t("components.list_with_screenshot_alt")} loading="lazy" />
</>
)}
</div>
@ -272,14 +279,14 @@ function ListWithScreenshot({ items, horizontal, cardExtra }: {
function FaqSection() {
return (
<Section className="faq" title="Frequently Asked Questions">
<Section className="faq" title={t("faq.title")}>
<div class="grid-2-cols">
<FaqItem question="Is there a mobile application?">Currently there is no official mobile application. However, if you have a server instance you can access it using a web browser and even install it as a PWA. For Android, there is an unofficial application called TriliumDroid that even works offline (same as a desktop client).</FaqItem>
<FaqItem question="Where is the data stored?">All your notes will be stored in an SQLite database in an application folder. The reasoning why Trilium uses a database instead of plain text files is both performance and some features would be much more difficult to implement such as clones (same note in multiple places in the tree). To find the application folder, simply go to the About window.</FaqItem>
<FaqItem question="Do I need a server to use Trilium?">No, the server allows access via a web browser and manages the synchronization if you have multiple devices. To get started, it's enough to download the desktop application and start using it.</FaqItem>
<FaqItem question="How well does the application scale with a large amount of notes?">Depending on usage, the application should be able to handle at least 100.000 notes without an issue. Do note that the sync process can sometimes fail if uploading many large files (&gt; 1 GB per file) since Trilium is meant more as a knowledge base application rather than a file store (like NextCloud, for example).</FaqItem>
<FaqItem question="Can I share my database over a network drive?">No, it's generally not a good idea to share a SQLite database over a network drive. Although sometimes it might work, there are chances that the database will get corrupted due to imperfect file locks over a network.</FaqItem>
<FaqItem question="How is my data protected?">By default, notes are not encrypted and can be read directly from the database. Once a note is marked as encrypted, the note is encrypted using AES-128-CBC.</FaqItem>
<FaqItem question={t("faq.mobile_question")}>{t("faq.mobile_answer")}</FaqItem>
<FaqItem question={t("faq.database_question")}>{t("faq.database_answer")}</FaqItem>
<FaqItem question={t("faq.server_question")}>{t("faq.server_answer")}</FaqItem>
<FaqItem question={t("faq.scaling_question")}>{t("faq.scaling_answer")}</FaqItem>
<FaqItem question={t("faq.network_share_question")}>{t("faq.network_share_answer")}</FaqItem>
<FaqItem question={t("faq.security_question")}>{t("faq.security_answer")}</FaqItem>
</div>
</Section>
);
@ -295,11 +302,11 @@ function FaqItem({ question, children }: { question: string; children: Component
function FinalCta() {
return (
<Section className="final-cta accented" title="Ready to get started with Trilium Notes?">
<p>Build your personal knowledge base with powerful features and full privacy.</p>
<Section className="final-cta accented" title={t("final_cta.title")}>
<p>{t("final_cta.description")}</p>
<div class="buttons">
<Button href="./get-started/" text="Get started" />
<Button href="./get-started/" text={t("final_cta.get_started")} />
</div>
</Section>
)

View File

@ -6,28 +6,37 @@ import buyMeACoffeeIcon from "../../assets/boxicons/bx-buy-me-a-coffee.svg?raw";
import Button, { Link } from "../../components/Button.js";
import Card from "../../components/Card.js";
import { usePageTitle } from "../../hooks.js";
import { t } from "../../i18n.js";
import { Trans } from "react-i18next";
export default function Donate() {
usePageTitle("Support us");
usePageTitle(t("support_us.title"));
return (
<>
<Section title="Support us" className="donate fill">
<Section title={t("support_us.title")} className="donate fill">
<div class="grid-2-cols">
<Card title="Financial donations">
<Card title={t("support_us.financial_donations_title")}>
<p>
Trilium is built and maintained with <Link href="https://github.com/TriliumNext/Trilium/graphs/commit-activity" openExternally>hundreds of hours of work</Link>.
Your support keeps it open-source, improves features, and covers costs such as hosting.
<Trans
i18nKey="support_us.financial_donations_description"
components={{ Link: <Link href="https://github.com/TriliumNext/Trilium/graphs/commit-activity" openExternally /> }}
/>
</p>
<p>Consider supporting the main developer (<Link href="https://github.com/eliandoran" openExternally>eliandoran</Link>) of the application via:</p>
<p>
<Trans
i18nKey="support_us.financial_donations_cta"
components={{ Link: <Link href="https://github.com/eliandoran" openExternally /> }}
/>
</p>
<ul class="donate-buttons">
<li>
<Button
iconSvg={githubIcon}
href="https://github.com/sponsors/eliandoran"
text="GitHub Sponsors"
text={t("support_us.github_sponsors")}
openExternally
/>
</li>
@ -36,7 +45,7 @@ export default function Donate() {
<Button
iconSvg={paypalIcon}
href="https://paypal.me/eliandoran"
text="PayPal"
text={t("support_us.paypal")}
openExternally
outline
/>
@ -46,7 +55,7 @@ export default function Donate() {
<Button
iconSvg={buyMeACoffeeIcon}
href="https://buymeacoffee.com/eliandoran"
text="Buy Me A Coffee"
text={t("support_us.buy_me_a_coffee")}
openExternally
outline
/>
@ -54,13 +63,27 @@ export default function Donate() {
</ul>
</Card>
<Card title="Other ways to contribute">
<Card title={t("contribute.title")}>
<ul>
<li>Translate the application into your native language via <Link href="https://hosted.weblate.org/engage/trilium/" openExternally>Weblate</Link>.</li>
<li>Interact with the community on <Link href="https://github.com/orgs/TriliumNext/discussions" openExternally>GitHub Discussions</Link> or on <Link href="https://matrix.to/#/#triliumnext:matrix.org" openExternally>Matrix</Link>.</li>
<li>Report bugs via <Link href="https://github.com/TriliumNext/Trilium/issues" openExternally>GitHub issues</Link>.</li>
<li>Improve the documentation by informing us on gaps in the documentation or contributing guides, FAQs or tutorials.</li>
<li>Spread the word: Share Trilium Notes with friends, or on blogs and social media.</li>
<li>
<Trans i18nKey="contribute.way_translate"
components={{ Link: <Link href="https://hosted.weblate.org/engage/trilium/" openExternally /> }} />
</li>
<li>
<Trans i18nKey="contribute.way_community"
components={{
Discussions: <Link href="https://github.com/orgs/TriliumNext/discussions" openExternally />,
Matrix: <Link href="https://matrix.to/#/#triliumnext:matrix.org" openExternally />
}}
/>
</li>
<li>
<Trans i18nKey="contribute.way_reports"
components={{ Link: <Link href="https://github.com/TriliumNext/Trilium/issues" openExternally /> }}
/>
</li>
<li><Trans i18nKey="contribute.way_document" /></li>
<li><Trans i18nKey="contribute.way_market" /></li>
</ul>
</Card>
</div>

View File

@ -1,13 +1,14 @@
import Section from "../components/Section.js";
import { usePageTitle } from "../hooks.js";
import { t } from "../i18n.js";
import "./_404.css";
export function NotFound() {
usePageTitle("404");
usePageTitle(t("404.title"));
return (
<Section title="404: Not Found" className="section-404">
The page you were looking for could not be found. Maybe it was deleted or the URL is incorrect.
<Section title={t("404.title")} className="section-404">
{t("404.description")}
</Section>
);
}

View File

@ -1,6 +1,7 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"composite": true,
"target": "ES2020",
"module": "ESNext",
"moduleResolution": "bundler",
@ -9,8 +10,8 @@
"jsxImportSource": "preact",
"skipLibCheck": true,
"paths": {
"react": ["./node_modules/preact/compat/"],
"react-dom": ["./node_modules/preact/compat/"]
"react": ["../../node_modules/preact/compat/"],
"react-dom": ["../../node_modules/preact/compat/"]
}
},
"include": ["node_modules/vite/client.d.ts", "**/*"],

11
pnpm-lock.yaml generated
View File

@ -765,6 +765,12 @@ importers:
apps/website:
dependencies:
i18next:
specifier: 25.6.0
version: 25.6.0(typescript@5.9.3)
i18next-http-backend:
specifier: 3.0.2
version: 3.0.2(encoding@0.1.13)
preact:
specifier: 10.27.2
version: 10.27.2
@ -774,6 +780,9 @@ importers:
preact-render-to-string:
specifier: 6.6.2
version: 6.6.2(preact@10.27.2)
react-i18next:
specifier: 16.0.0
version: 16.0.0(i18next@25.6.0(typescript@5.9.3))(react-dom@19.1.0(react@16.14.0))(react@16.14.0)(typescript@5.9.3)
devDependencies:
'@preact/preset-vite':
specifier: 2.10.2
@ -14754,8 +14763,6 @@ snapshots:
'@ckeditor/ckeditor5-utils': 47.0.0
'@ckeditor/ckeditor5-watchdog': 47.0.0
es-toolkit: 1.39.5
transitivePeerDependencies:
- supports-color
'@ckeditor/ckeditor5-dev-build-tools@43.1.0(@swc/helpers@0.5.17)(tslib@2.8.1)(typescript@5.9.3)':
dependencies: