fix(website): hydration issues due to rendering on the server of client-side logic

This commit is contained in:
Elian Doran 2025-09-28 00:58:15 +03:00
parent bd2eb6fdbb
commit 5b673e753b
No known key found for this signature in database
4 changed files with 22 additions and 13 deletions

View File

@ -1,16 +1,18 @@
import { getRecommendedDownload } from "../download-helper.js";
import { getRecommendedDownload, RecommendedDownload } from "../download-helper.js";
import "./DownloadButton.css";
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";
interface DownloadButtonProps {
big?: boolean;
}
const recommendedDownload = getRecommendedDownload();
export default function DownloadButton({ big }: DownloadButtonProps) {
const [ recommendedDownload, setRecommendedDownload ] = useState<RecommendedDownload | null>();
useEffect(() => setRecommendedDownload(getRecommendedDownload()), []);
return (recommendedDownload &&
<Button
className={`download-button desktop-only ${big ? "big" : ""}`}

View File

@ -22,6 +22,13 @@ export interface DownloadMatrixEntry {
quickStartCode?: string;
}
export interface RecommendedDownload {
architecture: Architecture;
platform: Platform;
url: string;
name: string;
}
type DownloadMatrix = Record<App, { [ P in Platform ]?: DownloadMatrixEntry }>;
// Keep compatibility info inline with https://github.com/electron/electron/blob/main/README.md#platform-support.
@ -205,7 +212,7 @@ export function getPlatform(): Platform | null {
}
}
export function getRecommendedDownload() {
export function getRecommendedDownload(): RecommendedDownload | null {
if (typeof window === "undefined") return null;
const architecture = getArchitecture();

View File

@ -11,11 +11,11 @@ export function usePageTitle(title: string) {
}
export function useColorScheme() {
if (typeof window === "undefined") return;
const [ prefersDark, setPrefersDark ] = useState((window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches));
const defaultValue = (typeof window !== "undefined" && (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches));
const [ prefersDark, setPrefersDark ] = useState(defaultValue);
useEffect(() => {
if (typeof window === "undefined") return;
const mediaQueryList = window.matchMedia("(prefers-color-scheme: dark)");
const listener = () => setPrefersDark((window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches));

View File

@ -30,7 +30,7 @@ import tableIcon from "../../assets/boxicons/bx-table.svg?raw";
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 { useState } from 'preact/hooks';
import { useEffect, useState } from 'preact/hooks';
export function Home() {
usePageTitle("");
@ -51,22 +51,22 @@ export function Home() {
function HeroSection() {
const platform = getPlatform();
let screenshotUrl: string | null = null;
const colorScheme = useColorScheme();
const [ screenshotUrl, setScreenshotUrl ] = useState<string>();
if (colorScheme) {
useEffect(() => {
switch (platform) {
case "macos":
screenshotUrl = `/screenshot_desktop_mac_${colorScheme}.webp`;
setScreenshotUrl(`/screenshot_desktop_mac_${colorScheme}.webp`);
break;
case "linux":
break;
case "windows":
default:
screenshotUrl = `/screenshot_desktop_win_${colorScheme}.webp`;
setScreenshotUrl(`/screenshot_desktop_win_${colorScheme}.webp`);
break;
}
}
}, [ colorScheme ]);
return (
<Section className="hero-section">