diff --git a/src/app/(dashboard)/reverse-proxy/custom-domains/layout.tsx b/src/app/(dashboard)/reverse-proxy/custom-domains/layout.tsx
new file mode 100644
index 00000000..70529903
--- /dev/null
+++ b/src/app/(dashboard)/reverse-proxy/custom-domains/layout.tsx
@@ -0,0 +1,8 @@
+import { globalMetaTitle } from "@utils/meta";
+import type { Metadata } from "next";
+import BlankLayout from "@/layouts/BlankLayout";
+
+export const metadata: Metadata = {
+ title: `Custom Domains - Reverse Proxy - ${globalMetaTitle}`,
+};
+export default BlankLayout;
diff --git a/src/app/(dashboard)/reverse-proxy/custom-domains/page.tsx b/src/app/(dashboard)/reverse-proxy/custom-domains/page.tsx
new file mode 100644
index 00000000..d052c0ce
--- /dev/null
+++ b/src/app/(dashboard)/reverse-proxy/custom-domains/page.tsx
@@ -0,0 +1,70 @@
+"use client";
+
+import Breadcrumbs from "@components/Breadcrumbs";
+import InlineLink from "@components/InlineLink";
+import Paragraph from "@components/Paragraph";
+import SkeletonTable from "@components/skeletons/SkeletonTable";
+import { RestrictedAccess } from "@components/ui/RestrictedAccess";
+import { usePortalElement } from "@hooks/usePortalElement";
+import { ExternalLinkIcon } from "lucide-react";
+import React, { lazy, Suspense } from "react";
+import ReverseProxyIcon from "@/assets/icons/ReverseProxyIcon";
+import { usePermissions } from "@/contexts/PermissionsProvider";
+import ReverseProxiesProvider from "@/contexts/ReverseProxiesProvider";
+import { REVERSE_PROXY_CUSTOM_DOMAINS_DOCS_LINK } from "@/interfaces/ReverseProxy";
+import PageContainer from "@/layouts/PageContainer";
+
+const CustomDomainsTable = lazy(
+ () => import("@/modules/reverse-proxy/domain/CustomDomainsTable"),
+);
+
+export default function ReverseProxyCustomDomainsPage() {
+ const { permission } = usePermissions();
+
+ const { ref: headingRef, portalTarget } =
+ usePortalElement();
+
+ return (
+
+
+
+ }
+ />
+
+
+
Domains
+
+ Add and manage custom domains for your reverse proxy services.
+
+
+ Learn more about
+
+ Custom Domains
+
+
+ in our documentation.
+
+
+
+
+ }>
+
+
+
+
+
+ );
+}
diff --git a/src/app/(dashboard)/reverse-proxy/page.tsx b/src/app/(dashboard)/reverse-proxy/page.tsx
new file mode 100644
index 00000000..8f5c4973
--- /dev/null
+++ b/src/app/(dashboard)/reverse-proxy/page.tsx
@@ -0,0 +1,15 @@
+"use client";
+
+import FullScreenLoading from "@components/ui/FullScreenLoading";
+import { useRouter } from "next/navigation";
+import { useEffect } from "react";
+
+export default function ReverseProxyRedirectPage() {
+ const router = useRouter();
+
+ useEffect(() => {
+ router.replace("/reverse-proxy/services");
+ }, [router]);
+
+ return ;
+}
diff --git a/src/app/(dashboard)/reverse-proxy/services/layout.tsx b/src/app/(dashboard)/reverse-proxy/services/layout.tsx
new file mode 100644
index 00000000..b895c6b6
--- /dev/null
+++ b/src/app/(dashboard)/reverse-proxy/services/layout.tsx
@@ -0,0 +1,8 @@
+import { globalMetaTitle } from "@utils/meta";
+import type { Metadata } from "next";
+import BlankLayout from "@/layouts/BlankLayout";
+
+export const metadata: Metadata = {
+ title: `Services - Reverse Proxy - ${globalMetaTitle}`,
+};
+export default BlankLayout;
diff --git a/src/app/(dashboard)/reverse-proxy/services/page.tsx b/src/app/(dashboard)/reverse-proxy/services/page.tsx
new file mode 100644
index 00000000..24238b49
--- /dev/null
+++ b/src/app/(dashboard)/reverse-proxy/services/page.tsx
@@ -0,0 +1,83 @@
+"use client";
+
+import Breadcrumbs from "@components/Breadcrumbs";
+import InlineLink from "@components/InlineLink";
+import Paragraph from "@components/Paragraph";
+import SkeletonTable from "@components/skeletons/SkeletonTable";
+import { RestrictedAccess } from "@components/ui/RestrictedAccess";
+import { usePortalElement } from "@hooks/usePortalElement";
+import { ExternalLinkIcon } from "lucide-react";
+import React, { lazy, Suspense } from "react";
+import ReverseProxyIcon from "@/assets/icons/ReverseProxyIcon";
+import { usePermissions } from "@/contexts/PermissionsProvider";
+import ReverseProxiesProvider from "@/contexts/ReverseProxiesProvider";
+import { REVERSE_PROXY_DOCS_LINK } from "@/interfaces/ReverseProxy";
+import PageContainer from "@/layouts/PageContainer";
+import { Callout } from "@components/Callout";
+import { isNetBirdHosted } from "@utils/netbird";
+
+const ReverseProxyTable = lazy(
+ () => import("@/modules/reverse-proxy/table/ReverseProxyTable"),
+);
+
+export default function ReverseProxyServicesPage() {
+ const { permission } = usePermissions();
+
+ const { ref: headingRef, portalTarget } =
+ usePortalElement();
+
+ return (
+
+
+
+ }
+ />
+
+
+
Services
+
+ Expose services securely through NetBird's reverse proxy.
+
+
+ Learn more about
+
+ Services
+
+
+ in our documentation.
+
+
+ {isNetBirdHosted() ? (
+
+ NetBird's Reverse Proxy is currently in beta and available at
+ no cost during this period. Features, functionality, and pricing are
+ subject to change upon release.
+
+ ) : (
+
+ NetBird's Reverse Proxy is currently in beta. Features
+ and functionality are subject to change upon release.
+
+ )}
+