chore: refine v2 beta resources

This commit is contained in:
ajnart committed 2026-09-06 19:36:08 +02:00
1 parent 7ba04f8019
commit ce03ba8a59
5 files changed
+116 -76

No files matched your search

+1 -1
View File
@@ -41,7 +41,7 @@ body:
attributes: attributes:
label: Affected page, feature, or widget label: Affected page, feature, or widget
description: Name the exact page, widget, integration, container, sidebar, or action involved. description: Name the exact page, widget, integration, container, sidebar, or action involved.
placeholder: Board editor — moving a widget into a container placeholder: "Board editor: moving a widget into a container"
validations: validations:
required: true required: true
+1 -1
View File
@@ -13,7 +13,7 @@ import { IconArrowRight } from '@tabler/icons-react';
:::info Homarr v2 beta is available :::info Homarr v2 beta is available
There is no release date yet: Homarr v2 will become the default when it is ready. Read [what is new](https://v2.preview.homarr.dev/blog), try the [hosted preview](https://app-v2.preview.homarr.dev), [join us on Discord](https://discord.com/invite/aCsmEV5RgA), and [share your feedback](https://github.com/homarr-labs/homarr/issues/new?template=v2_beta_feedback.yml). Everyone uses Homarr differently, so every report helps us find what breaks or does not feel right before release. SQLite administrators can download a full backup directly from the beta announcement before changing images. There is no release date yet: Homarr v2 will become the default when it is ready. Read [what is new](https://v2.preview.homarr.dev/blog/2026/09/03/homarr-2.0), browse the [v2 documentation](https://v2.preview.homarr.dev/docs) and [Homarr Workshop](https://v2.preview.homarr.dev/workshop), try the [hosted preview](https://app-v2.preview.homarr.dev), [join us on Discord](https://discord.com/invite/aCsmEV5RgA), and [share your feedback](https://github.com/homarr-labs/homarr/issues/new?template=v2_beta_feedback.yml). Everyone uses Homarr differently, so every report helps us find what breaks or does not feel right before release. SQLite administrators can download a full backup directly from the beta announcement before changing images.
::: :::
@@ -1,5 +1,7 @@
export const v2BetaBlogUrl = "https://v2.preview.homarr.dev/blog"; export const v2BetaBlogUrl = "https://v2.preview.homarr.dev/blog/2026/09/03/homarr-2.0";
export const v2BetaDocsUrl = "https://v2.preview.homarr.dev/docs";
export const v2BetaPreviewUrl = "https://app-v2.preview.homarr.dev"; export const v2BetaPreviewUrl = "https://app-v2.preview.homarr.dev";
export const v2BetaWorkshopUrl = "https://v2.preview.homarr.dev/workshop";
export const v2BetaFeedbackUrl = "https://github.com/homarr-labs/homarr/issues/new?template=v2_beta_feedback.yml"; export const v2BetaFeedbackUrl = "https://github.com/homarr-labs/homarr/issues/new?template=v2_beta_feedback.yml";
export const v2BetaDiscussionUrl = "https://github.com/homarr-labs/homarr/issues/6600"; export const v2BetaDiscussionUrl = "https://github.com/homarr-labs/homarr/issues/6600";
export const discordInviteUrl = "https://discord.com/invite/aCsmEV5RgA"; export const discordInviteUrl = "https://discord.com/invite/aCsmEV5RgA";
@@ -11,14 +11,13 @@
.banner::after { .banner::after {
position: absolute; position: absolute;
z-index: -1; z-index: -1;
top: -1.75rem; right: -0.35rem;
right: 12%; bottom: -1.75rem;
color: rgb(255 255 255 / 9%); color: rgb(255 255 255 / 9%);
font-size: 5.5rem; font-size: 5.5rem;
font-weight: 900; font-weight: 900;
line-height: 1; line-height: 1;
content: "v2"; content: "v2";
transform: rotate(5deg);
} }
.copy { .copy {
@@ -40,14 +39,18 @@
.modalHero::after { .modalHero::after {
position: absolute; position: absolute;
z-index: -1; z-index: -1;
top: -3.5rem; right: -0.75rem;
right: 1.5rem; bottom: -3.25rem;
color: rgb(255 255 255 / 8%); color: rgb(255 255 255 / 8%);
font-size: 12rem; font-size: 12rem;
font-weight: 900; font-weight: 900;
line-height: 1; line-height: 1;
content: "v2"; content: "v2";
transform: rotate(5deg); }
.featureCard {
height: 100%;
background: light-dark(var(--mantine-color-white), var(--mantine-color-dark-7));
} }
.diffViewer { .diffViewer {
@@ -89,13 +92,3 @@
color: light-dark(var(--mantine-color-red-9), var(--mantine-color-red-3)); color: light-dark(var(--mantine-color-red-9), var(--mantine-color-red-3));
background: light-dark(var(--mantine-color-red-0), rgb(250 82 82 / 15%)); background: light-dark(var(--mantine-color-red-0), rgb(250 82 82 / 15%));
} }
@media (max-width: $mantine-breakpoint-xs) {
.banner::after {
right: 35%;
}
.modalHero::after {
right: -2rem;
}
}
@@ -1,7 +1,6 @@
"use client"; "use client";
import type { ReactNode } from "react"; import type { ReactNode } from "react";
import { useState } from "react";
import { import {
ActionIcon, ActionIcon,
Accordion, Accordion,
@@ -19,6 +18,7 @@ import {
} from "@mantine/core"; } from "@mantine/core";
import { import {
IconArrowsMove, IconArrowsMove,
IconBook2,
IconBrandCss3, IconBrandCss3,
IconBrandDiscord, IconBrandDiscord,
IconBrandGithub, IconBrandGithub,
@@ -38,7 +38,15 @@ import { setClientCookie } from "@homarr/common";
import { createModal, useModalAction } from "@homarr/modals"; import { createModal, useModalAction } from "@homarr/modals";
import { BackupExportButton } from "~/components/backup"; import { BackupExportButton } from "~/components/backup";
import { discordInviteUrl, v2BetaBlogUrl, v2BetaDiscussionUrl, v2BetaFeedbackUrl, v2BetaPreviewUrl } from "./constants"; import {
discordInviteUrl,
v2BetaBlogUrl,
v2BetaDiscussionUrl,
v2BetaDocsUrl,
v2BetaFeedbackUrl,
v2BetaPreviewUrl,
v2BetaWorkshopUrl,
} from "./constants";
import classes from "./v2-beta-announcement.module.css"; import classes from "./v2-beta-announcement.module.css";
const diffLineClassNames = { const diffLineClassNames = {
@@ -129,37 +137,35 @@ interface V2BetaAnnouncementModalProps {
} }
const V2BetaAnnouncementModal = createModal<V2BetaAnnouncementModalProps>(({ innerProps }) => { const V2BetaAnnouncementModal = createModal<V2BetaAnnouncementModalProps>(({ innerProps }) => {
const [openedSection, setOpenedSection] = useState<string | null>("workshop");
return ( return (
<Stack gap="lg"> <Stack gap="lg">
<Paper className={classes.modalHero} p={{ base: "lg", sm: "xl" }} radius="md"> <Paper className={classes.modalHero} p={{ base: "lg", sm: "xl" }} radius="md">
<Stack gap="sm" maw={760}> <Stack gap="sm" maw={760}>
<Title order={2}>Help us get Homarr v2 ready</Title> <Title order={2}>Help us get Homarr v2 ready</Title>
<Text> <Text>
There is no release date yet. Homarr v2 will become the default when it is ready—and we need you to test it There is no release date yet. Homarr v2 will become the default when it is ready, and we need you to test it
and share feedback before we can be confident enough to make that switch. and share feedback before we can be confident enough to make that switch.
</Text> </Text>
</Stack> </Stack>
</Paper> </Paper>
<Accordion variant="separated" radius="md" value={openedSection} onChange={setOpenedSection}> <SimpleGrid cols={{ base: 1, sm: 2 }} spacing="md">
<FeatureAccordionItem value="workshop" icon={<IconBrandCss3 size={20} />} title="Homarr Workshop"> <FeatureCard icon={<IconBrandCss3 size={21} />} title="Homarr Workshop">
Share and discover Custom Widgets and CSS made by the Homarr community. Share and discover Custom Widgets and CSS made by the Homarr community.
</FeatureAccordionItem> </FeatureCard>
<FeatureAccordionItem <FeatureCard icon={<IconArrowsMove size={21} />} title="Complete drag-and-drop rewrite">
value="drag-and-drop"
icon={<IconArrowsMove size={20} />}
title="Complete drag-and-drop rewrite"
>
Move, resize, multi-select, and arrange your dashboard with a board editor rebuilt from the ground up. Move, resize, multi-select, and arrange your dashboard with a board editor rebuilt from the ground up.
</FeatureAccordionItem> </FeatureCard>
<FeatureAccordionItem value="custom-widgets" icon={<IconWand size={20} />} title="Custom Widgets v2"> <FeatureCard icon={<IconWand size={21} />} title="Custom Widgets v2">
We think you can make almost any widget with live previews, API requests, options, actions, and validation. We think you can make almost any widget with live previews, API requests, options, actions, and validation.
</FeatureAccordionItem> </FeatureCard>
<FeatureAccordionItem value="assistant" icon={<IconRobot size={20} />} title="Homarr Assistant"> <FeatureCard icon={<IconRobot size={21} />} title="Homarr Assistant">
Ask questions, find what you need, and manage Homarr through permission-aware tools. Homarr Assistant can directly make a Custom Widget for you. Try giving it the API docs for your latest
</FeatureAccordionItem> selfhosted tool and asking it to build a custom widget for it.
</FeatureCard>
</SimpleGrid>
<Accordion variant="separated" radius="md">
<Accordion.Item value="installation"> <Accordion.Item value="installation">
<Accordion.Control <Accordion.Control
icon={ icon={
@@ -180,6 +186,18 @@ const V2BetaAnnouncementModal = createModal<V2BetaAnnouncementModalProps>(({ inn
<V2BetaInstallInstructions canExportBackup={innerProps.canExportBackup} /> <V2BetaInstallInstructions canExportBackup={innerProps.canExportBackup} />
</Accordion.Panel> </Accordion.Panel>
</Accordion.Item> </Accordion.Item>
<FaqAccordionItem value="current-data" title="Can I use my current Homarr data?">
Use the separate <code>homarr-v2</code> volume shown in the example. Keep your current volume untouched so you
can return to your current Homarr instance.
</FaqAccordionItem>
<FaqAccordionItem value="release-date" title="When will Homarr v2 be released?">
There is no release date yet. V2 will become the default when it is ready, after enough testing and feedback
gives us confidence in the release.
</FaqAccordionItem>
<FaqAccordionItem value="feedback" title="What makes a useful feedback report?">
Tell us exactly what happened and what you expected instead. Add screenshots or a recording, your resolution
and browser zoom, board column count, device, browser, and exact reproduction steps whenever possible.
</FaqAccordionItem>
</Accordion> </Accordion>
<Alert variant="light" color="red" icon={<IconHeartHandshake size={22} />} title="Your testing is essential"> <Alert variant="light" color="red" icon={<IconHeartHandshake size={22} />} title="Your testing is essential">
@@ -198,6 +216,28 @@ const V2BetaAnnouncementModal = createModal<V2BetaAnnouncementModalProps>(({ inn
> >
Try the hosted preview Try the hosted preview
</Button> </Button>
<Button
component="a"
href={v2BetaWorkshopUrl}
target="_blank"
rel="noopener noreferrer"
variant="light"
size="md"
leftSection={<IconBrandCss3 size={18} />}
>
Open Homarr Workshop
</Button>
<Button
component="a"
href={v2BetaDocsUrl}
target="_blank"
rel="noopener noreferrer"
variant="default"
size="md"
leftSection={<IconBook2 size={18} />}
>
Read the v2 docs
</Button>
<Button <Button
component="a" component="a"
href={v2BetaBlogUrl} href={v2BetaBlogUrl}
@@ -220,6 +260,17 @@ const V2BetaAnnouncementModal = createModal<V2BetaAnnouncementModalProps>(({ inn
> >
Join us on Discord Join us on Discord
</Button> </Button>
<Button
component="a"
href={v2BetaDiscussionUrl}
target="_blank"
rel="noopener noreferrer"
variant="default"
size="md"
rightSection={<IconExternalLink size={15} />}
>
Follow v2 development
</Button>
</SimpleGrid> </SimpleGrid>
<Button <Button
@@ -234,23 +285,6 @@ const V2BetaAnnouncementModal = createModal<V2BetaAnnouncementModalProps>(({ inn
> >
Report anything that breaks or feels wrong Report anything that breaks or feels wrong
</Button> </Button>
<Group justify="space-between" align="center">
<Text c="dimmed" size="xs" maw={720}>
Please use a separate volume for the beta and keep a backup of your current Homarr data.
</Text>
<Button
component="a"
href={v2BetaDiscussionUrl}
target="_blank"
rel="noopener noreferrer"
variant="subtle"
size="compact-sm"
rightSection={<IconExternalLink size={15} />}
>
Follow v2 development
</Button>
</Group>
</Stack> </Stack>
); );
}).withOptions({ }).withOptions({
@@ -265,11 +299,6 @@ interface V2BetaInstallInstructionsProps {
const V2BetaInstallInstructions = ({ canExportBackup }: V2BetaInstallInstructionsProps) => ( const V2BetaInstallInstructions = ({ canExportBackup }: V2BetaInstallInstructionsProps) => (
<Stack gap="lg"> <Stack gap="lg">
<Alert color="yellow" title="Keep your current Homarr data safe">
Run the beta with the separate <code>homarr-v2</code> volume shown below. Keep a backup, and do not point this
prerelease image at the only copy of your production data.
</Alert>
{canExportBackup ? ( {canExportBackup ? (
<Paper withBorder p="md" radius="md"> <Paper withBorder p="md" radius="md">
<Stack gap="sm"> <Stack gap="sm">
@@ -336,31 +365,47 @@ const V2BetaInstallInstructions = ({ canExportBackup }: V2BetaInstallInstruction
</Stack> </Stack>
); );
interface FeatureAccordionItemProps { interface FeatureCardProps {
value: string;
icon: ReactNode; icon: ReactNode;
title: string; title: string;
children: ReactNode; children: ReactNode;
} }
const FeatureAccordionItem = ({ value, icon, title, children }: FeatureAccordionItemProps) => ( const FeatureCard = ({ icon, title, children }: FeatureCardProps) => (
<Accordion.Item value={value}> <Paper className={classes.featureCard} withBorder p="md" radius="md">
<Accordion.Control <Group gap="sm" align="flex-start" wrap="nowrap">
icon={ <ThemeIcon variant="light" color="red" radius="md" size="lg">
<ThemeIcon variant="light" color="red" radius="md" size="lg"> {icon}
{icon} </ThemeIcon>
</ThemeIcon> <Box>
} <Text fw={750} size="sm">
aria-label={title} {title}
> </Text>
<Text fw={750}>{title}</Text>
</Accordion.Control>
<Accordion.Panel>
<Box pl={48}>
<Text c="dimmed" size="sm"> <Text c="dimmed" size="sm">
{children} {children}
</Text> </Text>
</Box> </Box>
</Group>
</Paper>
);
interface FaqAccordionItemProps {
value: string;
title: string;
children: ReactNode;
}
const FaqAccordionItem = ({ value, title, children }: FaqAccordionItemProps) => (
<Accordion.Item value={value}>
<Accordion.Control aria-label={title}>
<Text fw={700} size="sm">
{title}
</Text>
</Accordion.Control>
<Accordion.Panel>
<Text c="dimmed" size="sm">
{children}
</Text>
</Accordion.Panel> </Accordion.Panel>
</Accordion.Item> </Accordion.Item>
); );