diff --git a/web/docs/installation.md b/web/docs/installation.mdx
similarity index 92%
rename from web/docs/installation.md
rename to web/docs/installation.mdx
index 7dfa73c..85bd41b 100644
--- a/web/docs/installation.md
+++ b/web/docs/installation.mdx
@@ -4,8 +4,6 @@ sidebar_position: 20
# Installation
-
-
:::important
1. The plugin **must** be installed in the same namespace as the CloudNativePG
operator (typically `cnpg-system`).
@@ -56,17 +54,12 @@ Both checks are required before proceeding with the installation.
## Installing the Barman Cloud Plugin
+import { InstallationSnippet } from '@site/src/components/Installation';
+
Install the plugin using `kubectl` by applying the manifest for the latest
release:
-
-
-```sh
-kubectl apply -f \
- https://github.com/cloudnative-pg/plugin-barman-cloud/releases/download/v0.4.0/manifest.yaml
-```
-
-
+
Example output:
@@ -114,4 +107,3 @@ following command:
kubectl apply -f \
https://raw.githubusercontent.com/cloudnative-pg/plugin-barman-cloud/refs/heads/main/manifest.yaml
```
-
diff --git a/web/docs/migration.md b/web/docs/migration.md
index 3c4ba98..b91fa0d 100644
--- a/web/docs/migration.md
+++ b/web/docs/migration.md
@@ -13,7 +13,7 @@ If you're currently relying on the built-in Barman Cloud integration, you can
migrate seamlessly to the new **plugin-based architecture** using the Barman
Cloud Plugin, with **no downtime**. Follow these steps:
-- [Install the Barman Cloud Plugin](installation.md)
+- [Install the Barman Cloud Plugin](installation.mdx)
- Create an `ObjectStore` resource by translating the contents of the
`.spec.backup.barmanObjectStore` section from your existing `Cluster`
definition
diff --git a/web/docs/usage.md b/web/docs/usage.md
index 869dfe2..dcff072 100644
--- a/web/docs/usage.md
+++ b/web/docs/usage.md
@@ -6,7 +6,7 @@ sidebar_position: 30
-After [installing the plugin](installation.md) in the same namespace as the
+After [installing the plugin](installation.mdx) in the same namespace as the
CloudNativePG operator, enabling your PostgreSQL cluster to use the Barman
Cloud Plugin involves just a few steps:
diff --git a/web/src/components/HomepageFeatures/feature.tsx b/web/src/components/HomepageFeatures/feature.tsx
new file mode 100644
index 0000000..3a64556
--- /dev/null
+++ b/web/src/components/HomepageFeatures/feature.tsx
@@ -0,0 +1,49 @@
+import type {ComponentProps, ComponentType, ReactElement} from "react";
+import clsx from "clsx";
+import styles from "@site/src/components/HomepageFeatures/styles.module.css";
+import Heading from "@theme/Heading";
+
+type FeatureItem = {
+ title: string;
+ Svg: ComponentType>;
+ description: string;
+};
+
+function Feature({title, Svg, description}: FeatureItem): ReactElement {
+ return (
+
+
+ );
}
diff --git a/web/src/components/Installation/index.tsx b/web/src/components/Installation/index.tsx
new file mode 100644
index 0000000..064a0ea
--- /dev/null
+++ b/web/src/components/Installation/index.tsx
@@ -0,0 +1,16 @@
+import {ReactElement} from 'react';
+import CodeBlock from '@theme/CodeBlock';
+import {useCurrentVersion} from '@site/src/hooks/versions';
+
+// InstallationSnippet is the kubectl incantation to install the lastest
+// available version of the Barman Cloud Plugin.
+export function InstallationSnippet(): ReactElement {
+ const latest = useCurrentVersion('latestReleased');
+ return (
+
+ {`kubectl apply -f \\
+ https://github.com/cloudnative-pg/plugin-barman-cloud/releases/download/v${latest}/manifest.yaml`}
+
+ );
+}
+
diff --git a/web/src/hooks/versions.ts b/web/src/hooks/versions.ts
new file mode 100644
index 0000000..785cc2f
--- /dev/null
+++ b/web/src/hooks/versions.ts
@@ -0,0 +1,36 @@
+import {useActiveVersion, useLatestVersion, useVersions} from '@docusaurus/plugin-content-docs/client';
+
+
+export function useCurrentVersion(fallback: 'latest' | 'latestReleased' = 'latest'): string {
+ switch (fallback) {
+ case 'latestReleased':
+ return useLatestReleasedVersion();
+ case 'latest': {
+ const version = useActiveVersion('default');
+ return version?.name ?? useLatestVersion('default')?.name;
+ }
+ default:
+ // The following line ensures that if `fallback` is not 'latest' or 'latestReleased',
+ // an error is thrown. This can be useful for catching unexpected states.
+ throw new Error(`Unhandled fallback type: ${fallback}`);
+ }
+}
+
+export function useLatestReleasedVersion(): string {
+ const allVersions = useVersions('default');
+
+ // Filter out "current" to only consider versioned docs
+ const versionedDocs = allVersions.filter(version => version.name !== 'current');
+
+ // Handle the case where no versioned documents are found
+ if (versionedDocs.length === 0) {
+ return "unknown_version";
+ }
+
+ const sortedVersions = versionedDocs.sort((a, b) => {
+ return b.name.localeCompare(a.name, undefined, { numeric: true, sensitivity: 'base' });
+ });
+
+ // The latest version is the first in the sorted list since versionedDocs was not empty,
+ return sortedVersions[0].name;
+}
diff --git a/web/src/pages/index.tsx b/web/src/pages/index.tsx
index bc6fbe9..427ca31 100644
--- a/web/src/pages/index.tsx
+++ b/web/src/pages/index.tsx
@@ -1,4 +1,4 @@
-import type {ReactNode} from 'react';
+import type {ReactElement, ReactNode} from 'react';
import clsx from 'clsx';
import Link from '@docusaurus/Link';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
@@ -8,7 +8,7 @@ import Heading from '@theme/Heading';
import styles from './index.module.css';
-function HomepageHeader() {
+function HomepageHeader(): ReactElement {
const { siteConfig } = useDocusaurusContext();
return (
@@ -21,7 +21,7 @@ function HomepageHeader() {
);
}
-export default function Home(): ReactNode {
+export default function Home(): ReactElement {
const {siteConfig} = useDocusaurusContext();
return (