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
1 change: 1 addition & 0 deletions app/about/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type { Metadata } from "next"
import type { ComponentType } from "react"

export const metadata: Metadata = {
alternates: { canonical: "about/" },
title: "About RustFS | Next-Generation Distributed Object Storage for AI",
description: "Learn about RustFS, an Apache 2.0 open-source distributed object storage system built in Rust. Powering AI data centers with native RDMA and DPU acceleration.",
keywords: "about RustFS, RustFS project, open source object storage, distributed object storage, Rust infrastructure, NVIDIA Inception, RDMA storage, DPU hardware acceleration",
Expand Down
5 changes: 4 additions & 1 deletion app/blog/tag/[tag]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ export async function generateStaticParams() {
export async function generateMetadata({ params }: { params: Promise<{ tag: string }> }): Promise<Metadata> {
const { tag } = await params;
const label = await findTag(tag);
return { title: label ? `${label} | RustFS Blog` : "RustFS Blog" };
return {
title: label ? `${label} | RustFS Blog` : "RustFS Blog",
alternates: { canonical: `/blog/tag/${tag}/` },
};
}

export default async function BlogTagPage({ params }: { params: Promise<{ tag: string }> }) {
Expand Down
1 change: 1 addition & 0 deletions app/contact-us/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import ContactForm from '@/components/business/contact-form'
import type { Metadata } from 'next'

export const metadata: Metadata = {
alternates: { canonical: "contact-us/" },
title: "Contact Us | RustFS | The High-Performance, Apache 2.0 Object Storage for AI",
description: 'Get in touch with the RustFS team. Contact us for questions, support, or partnership opportunities.',
openGraph: {
Expand Down
1 change: 1 addition & 0 deletions app/contact/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import ContactForm from '@/components/business/contact-form'
import type { Metadata } from 'next'

export const metadata: Metadata = {
alternates: { canonical: "contact/" },
title: "Contact Us | RustFS | The High-Performance, Apache 2.0 Object Storage for AI",
description: 'Get in touch with the RustFS team. Contact us for questions, support, or partnership opportunities.',
openGraph: {
Expand Down
1 change: 1 addition & 0 deletions app/cookie-policy/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { Metadata } from 'next'
import { CookieSettingsButton } from '@/components/business/cookie-consent'

export const metadata: Metadata = {
alternates: { canonical: "cookie-policy/" },
title: 'Cookie Policy | RustFS',
description: 'Learn how RustFS uses cookies and similar technologies on the official website.',
}
Expand Down
1 change: 1 addition & 0 deletions app/demo/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ const notices = [
];

export const metadata: Metadata = {
alternates: { canonical: "demo/" },
title: "RustFS Demo | Public Demo Environment",
description:
"Review the RustFS public demo credentials, daily reset schedule, and data safety notice before entering the demo environment.",
Expand Down
1 change: 1 addition & 0 deletions app/download/cli/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { getLatestCliRelease } from '@/lib/github';
import type { Metadata } from 'next';

export const metadata: Metadata = {
alternates: { canonical: "download/cli/" },
title: 'Download RustFS CLI Client (rc) | Multi-Platform Install',
description: 'Install the RustFS rc command-line client with a package manager, native binary, Docker, or source build.',
};
Expand Down
1 change: 1 addition & 0 deletions app/download/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import DownloadPageClient from './components/download-page-client';
import type { Metadata } from 'next';

export const metadata: Metadata = {
alternates: { canonical: "download/" },
title: "Download & Install RustFS | Multi-OS & Cloud-Native Deployment",
description: 'Download RustFS Server and native CLI (rc). Install seamlessly on Linux, macOS, Windows, and NixOS using pre-built binaries, Docker images, or Kubernetes.',
keywords: 'download RustFS, install RustFS, RustFS binary, RustFS Docker, RustFS Kubernetes, RustFS CLI, RustFS command line, NixOS object storage, S3 server download, macOS, Linux, Windows, nixos',
Expand Down
1 change: 1 addition & 0 deletions app/download/server/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { getLatestRelease } from '@/lib/github';
import type { Metadata } from 'next';

export const metadata: Metadata = {
alternates: { canonical: "download/server/" },
title: 'Download RustFS Server | Linux, Docker & Kubernetes',
description: 'Install the RustFS server with a Linux binary, Docker, Compose, Kubernetes, macOS, or Windows.',
};
Expand Down
17 changes: 17 additions & 0 deletions app/en/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import type { Metadata } from "next";

// `/en/` client-redirects to the homepage; declare the homepage as canonical
// so search engines consolidate this duplicate URL into it.
export const metadata: Metadata = {
alternates: {
canonical: "/",
},
};

export default function EnLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return children;
}
1 change: 1 addition & 0 deletions app/erasure-code-calculator/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { Metadata } from "next";
import ErasureCodeCalculator from "@/components/business/erasure-code-calculator";

export const metadata: Metadata = {
alternates: { canonical: "erasure-code-calculator/" },
title: "RustFS Erasure Code Calculator",
description: "Calculate raw capacity, usable capacity, and failure tolerance for erasure coding.",
};
Expand Down
1 change: 1 addition & 0 deletions app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { getGitHubMetrics } from "@/lib/github";
import type { Metadata } from "next";

export const metadata: Metadata = {
alternates: { canonical: "/" },
title: "RustFS | High-Performance S3 Object Storage for AI & Cloud-Native",
description: 'RustFS is an open-source, Apache 2.0-licensed distributed object storage system built in Rust. A high-performance, drop-in replacement for MinIO and Amazon S3 engineered for AI workloads.',
keywords: 'RustFS, object storage, distributed storage, open source, Rust, Amazon S3, MinIO alternative, MinIO migration, Apache 2.0, cloud native storage, AI infrastructure',
Expand Down
1 change: 1 addition & 0 deletions app/pricing/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import Link from "next/link";
import type { Metadata } from "next";

export const metadata: Metadata = {
alternates: { canonical: "pricing/" },
title: "Pricing | RustFS",
description: "RustFS is Apache 2.0 open-source object storage. Contact the RustFS team for enterprise support, migration, and deployment planning.",
};
Expand Down
1 change: 1 addition & 0 deletions app/privacy-policy/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { Metadata } from "next";

export const metadata: Metadata = {
alternates: { canonical: "privacy-policy/" },
title: "Privacy Policy | RustFS",
description:
"Learn how RustFS handles privacy for self-hosted software deployments and the RustFS official website.",
Expand Down
1 change: 1 addition & 0 deletions app/product/data-management/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import FeaturePage, { type FeaturePageSection } from "@/components/business/feat
import type { Metadata } from "next";

export const metadata: Metadata = {
alternates: { canonical: "product/data-management/" },
title: "Data Management & S3 Tables | RustFS High-Performance Storage",
description:
"Optimize data management with RustFS. Benefit from full S3 compatibility, automated lifecycle management, and native Iceberg support powered by S3 Tables to lower TCO and accelerate AI and big data workloads.",
Expand Down
1 change: 1 addition & 0 deletions app/product/high-availability-scale/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import FeaturePage, { type FeaturePageSection } from "@/components/business/feat
import type { Metadata } from "next";

export const metadata: Metadata = {
alternates: { canonical: "product/high-availability-scale/" },
title: "RustFS High Availability & Scalability | Enterprise Distributed Storage",
description:
"Discover RustFS enterprise distributed architecture. Experience limitless scaling from PB to EB levels with distributed EC, automated self-healing, and absolute data reliability.",
Expand Down
1 change: 1 addition & 0 deletions app/product/multiple-protocol-access/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import FeaturePage, { type FeaturePageSection } from "@/components/business/feat
import type { Metadata } from "next";

export const metadata: Metadata = {
alternates: { canonical: "product/multiple-protocol-access/" },
title: "Native Multi-Protocol Access | S3, Swift, WebDAV, FTP(s) & MCP | RustFS",
description: "Connect RustFS natively to any workload via S3, Swift, FTP(s), WebDAV, and MCP. Zero code modifications, no legacy proxies, and absolute multi-protocol data coexistence.",
keywords: [
Expand Down
1 change: 1 addition & 0 deletions app/product/operational-observability/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { Metadata } from "next";
import Link from "next/link";

export const metadata: Metadata = {
alternates: { canonical: "product/operational-observability/" },
title: "RustFS Cluster Operations & OTEL Observability | Enterprise Management",
description: "Simplify RustFS management with an intuitive console, rich rc CLI, and full-stack OTEL observability. Deploy Prometheus, Grafana, and Loki with one click for real-time cluster insights.",
keywords: [
Expand Down
1 change: 1 addition & 0 deletions app/product/security-compliance/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import FeaturePage, { type FeaturePageSection } from "@/components/business/feat
import type { Metadata } from "next";

export const metadata: Metadata = {
alternates: { canonical: "product/security-compliance/" },
title: "Security & Compliance | RustFS",
description: "RustFS provides enterprise-grade authentication, authorization, log auditing, event handling, SSE/KMS encryption, OIDC SSO, and mTLS security controls.",
keywords: [
Expand Down
4 changes: 2 additions & 2 deletions app/rustfs-config-generator/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@ export const metadata: Metadata = {
"RustFS configuration file",
],
alternates: {
canonical: "/rustfs-config-generator",
canonical: "/rustfs-config-generator/",
},
openGraph: {
title: "RustFS Config Generator | Generate /etc/default/rustfs Online",
description:
"Generate a RustFS /etc/default/rustfs config file in seconds — set S3 API and console ports, volumes, access keys, log level, and OpenTelemetry.",
type: "website",
url: "/rustfs-config-generator",
url: "/rustfs-config-generator/",
locale: "en_US",
siteName: "RustFS",
images: [
Expand Down
17 changes: 17 additions & 0 deletions app/zh/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import type { Metadata } from "next";

// `/zh/` client-redirects to the Chinese site; declare that target as canonical
// so search engines consolidate this URL into rustfs.com.cn.
export const metadata: Metadata = {
alternates: {
canonical: "https://rustfs.com.cn/",
},
};

export default function ZhLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return children;
}