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
18 changes: 8 additions & 10 deletions apps/registry/app/[locale]/build/[slug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ import { setRequestLocale } from "next-intl/server";
import { Footer } from "@/components/footer/footer";
import { type Locale, routing } from "@/i18n/routing";
import { resolveAiComponent } from "@/lib/ai-seo";
import { breadcrumbLd, faqPageLd, jsonLdScriptAttributes } from "@/lib/jsonld";
import {
breadcrumbTrailLd,
faqPageLd,
jsonLdScriptAttributes,
} from "@/lib/jsonld";
import { generateOGMetadata, generateTwitterMetadata } from "@/lib/og";
import { canonical, languageAlternates, localizePathname } from "@/lib/seo";
import { getSidebarSections } from "@/lib/sidebar-sections";
Expand All @@ -18,8 +22,6 @@ type Props = {
readonly params: Promise<{ locale: Locale; slug: string }>;
};

const SITE_URL = process.env.NEXT_PUBLIC_SITE_URL ?? "https://ui.vllnt.com";

export function generateStaticParams() {
return routing.locales.flatMap((locale) =>
USE_CASES.map((useCase) => ({ locale, slug: useCase.slug })),
Expand Down Expand Up @@ -77,13 +79,9 @@ export default async function UseCasePage({ params }: Props) {
<>
<script
{...jsonLdScriptAttributes([
breadcrumbLd([
{ name: "Home", url: SITE_URL },
{ name: "AI components", url: `${SITE_URL}/ai` },
{
name: useCase.title,
url: `${SITE_URL}/build/${useCase.slug}`,
},
breadcrumbTrailLd(locale, [
{ name: "AI components", path: "/ai" },
{ name: useCase.title, path: `/build/${useCase.slug}` },
]),
faqPageLd(useCase.faq),
])}
Expand Down
11 changes: 4 additions & 7 deletions apps/registry/app/[locale]/changelog/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,11 @@ import { setRequestLocale } from "next-intl/server";

import type { Locale } from "@/i18n/routing";
import { type ChangelogTypeFilter, getChangelogEntries } from "@/lib/changelog";
import { breadcrumbLd, jsonLdScript } from "@/lib/jsonld";
import { breadcrumbTrailLd, jsonLdScript } from "@/lib/jsonld";
import { generateOGMetadata, generateTwitterMetadata } from "@/lib/og";
import { canonical, languageAlternates, localizePathname } from "@/lib/seo";
import { getSidebarSections } from "@/lib/sidebar-sections";

const SITE_URL = process.env.NEXT_PUBLIC_SITE_URL ?? "https://ui.vllnt.com";

type SearchParameters = {
readonly from?: string;
readonly to?: string;
Expand Down Expand Up @@ -158,9 +156,8 @@ export default async function ChangelogPage({
<script
dangerouslySetInnerHTML={{
__html: jsonLdScript([
breadcrumbLd([
{ name: "Home", url: SITE_URL },
{ name: "Changelog", url: `${SITE_URL}/changelog` },
breadcrumbTrailLd(locale, [
{ name: "Changelog", path: "/changelog" },
]),
{
"@context": "https://schema.org",
Expand All @@ -170,7 +167,7 @@ export default async function ChangelogPage({
: {}),
description: DESCRIPTION,
headline: "VLLNT UI Changelog",
mainEntityOfPage: `${SITE_URL}/changelog`,
mainEntityOfPage: canonical("/changelog", locale),
publisher: {
"@type": "Organization",
name: "VLLNT",
Expand Down
15 changes: 5 additions & 10 deletions apps/registry/app/[locale]/components/[slug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { getAiSeo } from "@/lib/ai-seo";
import componentMetadata from "@/lib/component-metadata.json";
import { getComponentSeo } from "@/lib/component-seo";
import {
breadcrumbLd,
breadcrumbTrailLd,
faqPageLd,
jsonLdScriptAttributes,
softwareSourceCodeLd,
Expand Down Expand Up @@ -237,24 +237,19 @@ export default async function ComponentPage(props: Props) {
: []),
] as { id: string; title: string }[];

const SITE_URL = process.env.NEXT_PUBLIC_SITE_URL ?? "https://ui.vllnt.com";

return (
<>
<script
{...jsonLdScriptAttributes([
softwareSourceCodeLd({
description: displayDescription,
locale,
name: component.name,
title: displayTitle,
}),
breadcrumbLd([
{ name: "Home", url: SITE_URL },
{ name: "Components", url: `${SITE_URL}/components` },
{
name: displayTitle,
url: `${SITE_URL}/components/${component.name}`,
},
breadcrumbTrailLd(locale, [
{ name: "Components", path: "/components" },
{ name: displayTitle, path: `/components/${component.name}` },
]),
...(componentSeo?.faqs.length ? [faqPageLd(componentSeo.faqs)] : []),
])}
Expand Down
13 changes: 13 additions & 0 deletions apps/registry/app/[locale]/components/[slug]/playground/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { PlaygroundCodePanel } from "@/components/playground";
import { StorybookEmbed } from "@/components/storybook-embed";
import { type Locale, routing } from "@/i18n/routing";
import componentMetadata from "@/lib/component-metadata.json";
import { breadcrumbTrailLd, jsonLdScriptAttributes } from "@/lib/jsonld";
import { generateOGMetadata, generateTwitterMetadata } from "@/lib/og";
import {
getPlaygroundExample,
Expand Down Expand Up @@ -111,6 +112,18 @@ export default async function ComponentPlaygroundPage(props: Props) {

return (
<>
<script
{...jsonLdScriptAttributes(
breadcrumbTrailLd(locale, [
{ name: "Components", path: "/components" },
{ name: displayTitle, path: `/components/${component.name}` },
{
name: "Playground",
path: `/components/${component.name}/playground`,
},
]),
)}
/>
<Sidebar
sections={getSidebarSections(getCategoryForComponent(slug), locale)}
/>
Expand Down
23 changes: 23 additions & 0 deletions apps/registry/app/[locale]/components/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ import { setRequestLocale } from "next-intl/server";
import { ComponentCard } from "@/components/component-card";
import type { Locale } from "@/i18n/routing";
import { getPageContent } from "@/lib/content";
import {
breadcrumbTrailLd,
collectionPageLd,
jsonLdScriptAttributes,
} from "@/lib/jsonld";
import { generateOGMetadata, generateTwitterMetadata } from "@/lib/og";
import { canonical, languageAlternates, localizePathname } from "@/lib/seo";
import {
Expand Down Expand Up @@ -53,6 +58,24 @@ export default async function ComponentsPage({ params }: Props) {

return (
<>
<script
{...jsonLdScriptAttributes([
breadcrumbTrailLd(locale, [
{ name: "Components", path: "/components" },
]),
collectionPageLd({
description: `Browse all ${components.length} accessible React components in VLLNT UI — installable with the shadcn CLI.`,
items: groupedComponents.flatMap((group) =>
group.items.map((item) => ({
name: item.title,
url: canonical(`/components/${item.name}`, locale),
})),
),
title: "Components",
url: canonical("/components", locale),
}),
])}
/>
<Sidebar sections={getSidebarSections(undefined, locale)} />
<main className="flex-1 overflow-y-auto bg-background">
<div className="container mx-auto px-4 py-16 lg:px-8">
Expand Down
13 changes: 5 additions & 8 deletions apps/registry/app/[locale]/docs/[slug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,14 @@ import { type Locale, routing } from "@/i18n/routing";
import { getPageContent } from "@/lib/content";
import { DOCS_PAGES, getDocsPage, getDocsPath } from "@/lib/docs-pages";
import {
breadcrumbLd,
breadcrumbTrailLd,
jsonLdScriptAttributes,
techArticleLd,
} from "@/lib/jsonld";
import { generateOGMetadata, generateTwitterMetadata } from "@/lib/og";
import { canonical, languageAlternates, localizePathname } from "@/lib/seo";
import { getSidebarSections } from "@/lib/sidebar-sections";

const SITE_URL = process.env.NEXT_PUBLIC_SITE_URL ?? "https://ui.vllnt.com";

type Props = {
params: Promise<{ locale: Locale; slug: string }>;
};
Expand Down Expand Up @@ -123,17 +121,16 @@ export default async function DocsSlugPage(props: Props) {
docsPage.slug === "changelog"
? `${content}\n\n${await readChangelog()}`
: content;
const pageUrl = `${SITE_URL}${getDocsPath(docsPage)}`;
const pageUrl = canonical(getDocsPath(docsPage), locale);

return (
<>
<Script
id={`docs-${docsPage.slug}-json-ld`}
{...jsonLdScriptAttributes([
breadcrumbLd([
{ name: "Home", url: SITE_URL },
{ name: "Docs", url: `${SITE_URL}/docs` },
{ name: frontmatter.title, url: pageUrl },
breadcrumbTrailLd(locale, [
{ name: "Docs", path: "/docs" },
{ name: frontmatter.title, path: getDocsPath(docsPage) },
]),
techArticleLd({
description: frontmatter.description,
Expand Down
11 changes: 3 additions & 8 deletions apps/registry/app/[locale]/docs/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,14 @@ import type { Locale } from "@/i18n/routing";
import { getPageContent } from "@/lib/content";
import { DOCS_PAGES, getDocsPath } from "@/lib/docs-pages";
import {
breadcrumbLd,
breadcrumbTrailLd,
jsonLdScriptAttributes,
techArticleLd,
} from "@/lib/jsonld";
import { generateOGMetadata, generateTwitterMetadata } from "@/lib/og";
import { canonical, languageAlternates, localizePathname } from "@/lib/seo";
import { getSidebarSections } from "@/lib/sidebar-sections";

const SITE_URL = process.env.NEXT_PUBLIC_SITE_URL ?? "https://ui.vllnt.com";

type Props = {
readonly params: Promise<{ locale: Locale }>;
};
Expand Down Expand Up @@ -60,15 +58,12 @@ export default async function DocumentationPage({ params }: Props) {
<Script
id="docs-json-ld"
{...jsonLdScriptAttributes([
breadcrumbLd([
{ name: "Home", url: SITE_URL },
{ name: "Docs", url: `${SITE_URL}/docs` },
]),
breadcrumbTrailLd(locale, [{ name: "Docs", path: "/docs" }]),
techArticleLd({
description:
"Learn how to use VLLNT UI components in your projects.",
title: "Documentation",
url: `${SITE_URL}/docs`,
url: canonical("/docs", locale),
}),
])}
/>
Expand Down
15 changes: 6 additions & 9 deletions apps/registry/app/[locale]/families/[category]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { type Locale, routing } from "@/i18n/routing";
import { getFamilyCopy } from "@/lib/family-copy";
import { getFamilyGroups } from "@/lib/family-groups";
import {
breadcrumbLd,
breadcrumbTrailLd,
collectionPageLd,
faqPageLd,
jsonLdScriptAttributes,
Expand All @@ -29,8 +29,6 @@ type Props = {
readonly params: Promise<{ category: string; locale: Locale }>;
};

const SITE_URL = process.env.NEXT_PUBLIC_SITE_URL ?? "https://ui.vllnt.com";

function findFamily(category: string) {
return groupedComponents.find((group) => group.category === category);
}
Expand Down Expand Up @@ -109,19 +107,18 @@ export default async function FamilyPage({ params }: Props) {
<>
<script
{...jsonLdScriptAttributes([
breadcrumbLd([
{ name: "Home", url: SITE_URL },
{ name: "Components", url: `${SITE_URL}/components` },
{ name: group.label, url: `${SITE_URL}${pathname}` },
breadcrumbTrailLd(locale, [
{ name: "Components", path: "/components" },
{ name: group.label, path: pathname },
]),
collectionPageLd({
description,
items: group.items.map((item) => ({
name: item.title,
url: `${SITE_URL}/components/${item.name}`,
url: canonical(`/components/${item.name}`, locale),
})),
title: `${group.label} components`,
url: `${SITE_URL}${pathname}`,
url: canonical(pathname, locale),
}),
...(copy && copy.faq.length > 0 ? [faqPageLd(copy.faq)] : []),
])}
Expand Down
14 changes: 6 additions & 8 deletions apps/registry/app/[locale]/families/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { setRequestLocale } from "next-intl/server";
import { Footer } from "@/components/footer/footer";
import type { Locale } from "@/i18n/routing";
import {
breadcrumbLd,
breadcrumbTrailLd,
collectionPageLd,
jsonLdScriptAttributes,
} from "@/lib/jsonld";
Expand All @@ -23,7 +23,6 @@ type Props = {
readonly params: Promise<{ locale: Locale }>;
};

const SITE_URL = process.env.NEXT_PUBLIC_SITE_URL ?? "https://ui.vllnt.com";
const PATHNAME = "/families";
const TITLE = "Component families";
const DESCRIPTION =
Expand Down Expand Up @@ -59,19 +58,18 @@ export default async function FamiliesPage({ params }: Props) {
<>
<script
{...jsonLdScriptAttributes([
breadcrumbLd([
{ name: "Home", url: SITE_URL },
{ name: "Components", url: `${SITE_URL}/components` },
{ name: "Families", url: `${SITE_URL}${PATHNAME}` },
breadcrumbTrailLd(locale, [
{ name: "Components", path: "/components" },
{ name: "Families", path: PATHNAME },
]),
collectionPageLd({
description: DESCRIPTION,
items: groupedComponents.map((group) => ({
name: `${group.label} components`,
url: `${SITE_URL}${familyPath(group.category)}`,
url: canonical(familyPath(group.category), locale),
})),
title: TITLE,
url: `${SITE_URL}${PATHNAME}`,
url: canonical(PATHNAME, locale),
}),
])}
/>
Expand Down
11 changes: 11 additions & 0 deletions apps/registry/app/[locale]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { setRequestLocale } from "next-intl/server";

import { Landing } from "@/components/landing/landing";
import type { Locale } from "@/i18n/routing";
import { jsonLdScriptAttributes, softwareApplicationLd } from "@/lib/jsonld";
import { getNpmDistributionTags } from "@/lib/npm-version";
import { generateOGMetadata, generateTwitterMetadata } from "@/lib/og";
import { canonical, languageAlternates } from "@/lib/seo";
Expand Down Expand Up @@ -43,9 +44,19 @@ export async function generateMetadata({ params }: Props): Promise<Metadata> {
export default async function HomePage({ params }: Props) {
const { locale } = await params;
setRequestLocale(locale);
const componentCount = getComponentCount();

return (
<>
<script
{...jsonLdScriptAttributes(
softwareApplicationLd({
description: `Open-source React UI components and design system for building AI apps — ${componentCount} accessible components installable with the shadcn CLI and readable by AI agents via llms.txt.`,
name: "VLLNT UI",
url: canonical("/", locale),
}),
)}
/>
<Sidebar sections={getSidebarSections(undefined, locale)} />
<main className="flex-1 overflow-y-auto bg-background">
<Landing />
Expand Down
Loading
Loading