diff --git a/components/api-reference/ApiReferenceLayout.tsx b/components/api-reference/ApiReferenceLayout.tsx
index 770cff5ce..2b5740cd5 100644
--- a/components/api-reference/ApiReferenceLayout.tsx
+++ b/components/api-reference/ApiReferenceLayout.tsx
@@ -1,4 +1,4 @@
-import { useEffect, useRef } from "react";
+import { useEffect, useMemo, useRef } from "react";
import { useRouter } from "next/router";
import Meta from "@/components/Meta";
import { Page as TelegraphPage } from "@/components/ui/Page";
@@ -12,6 +12,12 @@ interface Breadcrumb {
href: string;
}
+type PageNeighbor = {
+ title: string;
+ path: string;
+ slug: string;
+};
+
interface ApiReferenceLayoutProps {
children: React.ReactNode;
sidebarData: SidebarData;
@@ -52,6 +58,56 @@ function convertToLegacySidebarFormat(
return [...preSidebarContent, ...resourceSections];
}
+/**
+ * Get the previous and next sections based on the current path.
+ * Sections are the top-level items in the sidebar (overview + resources).
+ */
+function getSectionNavigation(
+ currentPath: string | undefined,
+ sidebarContent: LegacySidebarSection[],
+): {
+ prevSection: PageNeighbor | undefined;
+ nextSection: PageNeighbor | undefined;
+} {
+ if (!currentPath) {
+ return { prevSection: undefined, nextSection: undefined };
+ }
+
+ // Find which section the current path belongs to
+ const currentSectionIndex = sidebarContent.findIndex((section) => {
+ return currentPath.startsWith(section.slug);
+ });
+
+ if (currentSectionIndex === -1) {
+ return { prevSection: undefined, nextSection: undefined };
+ }
+
+ let prevSection: PageNeighbor | undefined = undefined;
+ let nextSection: PageNeighbor | undefined = undefined;
+
+ // Get previous section
+ if (currentSectionIndex > 0) {
+ const prev = sidebarContent[currentSectionIndex - 1];
+ prevSection = {
+ title: prev.title || "",
+ path: prev.slug,
+ slug: prev.slug,
+ };
+ }
+
+ // Get next section
+ if (currentSectionIndex < sidebarContent.length - 1) {
+ const next = sidebarContent[currentSectionIndex + 1];
+ nextSection = {
+ title: next.title || "",
+ path: next.slug,
+ slug: next.slug,
+ };
+ }
+
+ return { prevSection, nextSection };
+}
+
export function ApiReferenceLayout({
children,
sidebarData,
@@ -81,6 +137,12 @@ export function ApiReferenceLayout({
preSidebarContent,
);
+ // Get section navigation (prev/next sections)
+ const { prevSection, nextSection } = useMemo(
+ () => getSectionNavigation(currentPath, sidebarContent),
+ [currentPath, sidebarContent],
+ );
+
// For per-resource pages, currentPath is the resource base path (e.g., /api-reference/users)
// This enables same-page routing for links within the current resource
const sidebarContextValue = {
@@ -131,6 +193,10 @@ export function ApiReferenceLayout({
}
/>
{children}
+
diff --git a/layouts/CliReferenceLayout.tsx b/layouts/CliReferenceLayout.tsx
index ed95133e0..ae9aee21e 100644
--- a/layouts/CliReferenceLayout.tsx
+++ b/layouts/CliReferenceLayout.tsx
@@ -1,4 +1,4 @@
-import React from "react";
+import React, { useMemo } from "react";
import { Page } from "@/components/ui/Page";
import { slugToPaths } from "../lib/content";
import Meta from "../components/Meta";
@@ -7,6 +7,63 @@ import { useInitialScrollState } from "../components/ui/Page/helpers";
import { CLI_SIDEBAR } from "../data/sidebars/cliSidebar";
import { ContentActions } from "../components/ui/ContentActions";
import { useScrollToTop } from "../hooks/useScrollToTop";
+import { SidebarContent } from "../data/types";
+
+type PageNeighbor = {
+ title: string;
+ path: string;
+ slug: string;
+};
+
+/**
+ * Get the previous and next sections based on the current path.
+ * Sections are the top-level items in the CLI sidebar.
+ */
+function getSectionNavigation(
+ currentPath: string | undefined,
+ sidebarContent: SidebarContent[],
+): {
+ prevSection: PageNeighbor | undefined;
+ nextSection: PageNeighbor | undefined;
+} {
+ if (!currentPath) {
+ return { prevSection: undefined, nextSection: undefined };
+ }
+
+ // Find which section the current path belongs to
+ const currentSectionIndex = sidebarContent.findIndex((section) => {
+ return currentPath.startsWith(section.slug);
+ });
+
+ if (currentSectionIndex === -1) {
+ return { prevSection: undefined, nextSection: undefined };
+ }
+
+ let prevSection: PageNeighbor | undefined = undefined;
+ let nextSection: PageNeighbor | undefined = undefined;
+
+ // Get previous section
+ if (currentSectionIndex > 0) {
+ const prev = sidebarContent[currentSectionIndex - 1];
+ prevSection = {
+ title: prev.title,
+ path: prev.slug,
+ slug: prev.slug,
+ };
+ }
+
+ // Get next section
+ if (currentSectionIndex < sidebarContent.length - 1) {
+ const next = sidebarContent[currentSectionIndex + 1];
+ nextSection = {
+ title: next.title,
+ path: next.slug,
+ slug: next.slug,
+ };
+ }
+
+ return { prevSection, nextSection };
+}
interface CliReferenceLayoutProps {
frontMatter: {
@@ -37,6 +94,15 @@ export const CliReferenceLayout = ({
const resource = router.query.resource as string;
const mdPath = resource ? `/cli/${resource}.md` : undefined;
+ // Build the current section path for navigation
+ const currentSectionPath = resource ? `/cli/${resource}` : "/cli/overview";
+
+ // Get section navigation (prev/next sections)
+ const { prevSection, nextSection } = useMemo(
+ () => getSectionNavigation(currentSectionPath, CLI_SIDEBAR),
+ [currentSectionPath],
+ );
+
return (
{children}
+
diff --git a/pages/api-reference/index.tsx b/pages/api-reference/index.tsx
index 2a0961597..d91f3f973 100644
--- a/pages/api-reference/index.tsx
+++ b/pages/api-reference/index.tsx
@@ -27,6 +27,7 @@ function ApiReferenceOverview({
preSidebarContent={API_REFERENCE_OVERVIEW_CONTENT}
title="API reference"
description="Complete reference documentation for the Knock API."
+ currentPath="/api-reference/overview"
>
diff --git a/pages/mapi-reference/index.tsx b/pages/mapi-reference/index.tsx
index ae7925df4..5b3ce4866 100644
--- a/pages/mapi-reference/index.tsx
+++ b/pages/mapi-reference/index.tsx
@@ -27,6 +27,7 @@ function MapiReferenceOverview({
preSidebarContent={MAPI_REFERENCE_OVERVIEW_CONTENT}
title="Management API reference"
description="Complete reference documentation for the Knock Management API."
+ currentPath="/mapi-reference/overview"
>