diff --git a/src/components/PageBody/PageBody.tsx b/src/components/PageBody/PageBody.tsx
index ae65a897f..18ac29982 100644
--- a/src/components/PageBody/PageBody.tsx
+++ b/src/components/PageBody/PageBody.tsx
@@ -1,6 +1,7 @@
import { Revision, RevisionPageDocument, Space } from '@gitbook/api';
import { PageHeader } from './PageHeader';
import { PageDocument } from './PageDocument';
+import { PageFooterNavigation } from './PageFooterNavigation';
export function PageBody(props: { space: Space; revision: Revision; page: RevisionPageDocument }) {
const { space, revision, page } = props;
@@ -9,6 +10,7 @@ export function PageBody(props: { space: Space; revision: Revision; page: Revisi
+
);
}
diff --git a/src/components/PageBody/PageFooterNavigation.tsx b/src/components/PageBody/PageFooterNavigation.tsx
new file mode 100644
index 000000000..9b94d239f
--- /dev/null
+++ b/src/components/PageBody/PageFooterNavigation.tsx
@@ -0,0 +1,60 @@
+import { pageHref } from "@/lib/links";
+import { resolvePrevNextPages } from "@/lib/pages";
+import { tcls } from "@/lib/tailwind";
+import { Revision, RevisionPageDocument } from "@gitbook/api";
+import Link from "next/link";
+
+/**
+ * Show cards to go to previous/next pages at the bottom.
+ */
+export function PageFooterNavigation(props: {
+ revision: Revision;
+ page: RevisionPageDocument;
+}) {
+ const { revision, page } = props;
+ const { previous, next } = resolvePrevNextPages(revision, page);
+
+ return (
+
+ {previous ? (
+
+ ) : null}
+ {next ? (
+
+ ) : null}
+
+ )
+}
+
+function NavigationCard(props: {
+ icon: React.ReactNode;
+ label: string;
+ title: string;
+ href: string;
+ reversed?: boolean;
+}) {
+ const { icon, label, title, href, reversed } = props;
+
+ return (
+
+
+ {label}
+ {title}
+
+
+ {icon}
+
+
+ )
+}
diff --git a/src/lib/pages.ts b/src/lib/pages.ts
index 2ec729ee3..5c8248d99 100644
--- a/src/lib/pages.ts
+++ b/src/lib/pages.ts
@@ -73,6 +73,29 @@ export function resolvePageId(
return iteratePages(revision.pages, []);
}
+/**
+ * Resolve the next/previous page before another one.
+ */
+export function resolvePrevNextPages(
+ revision: Revision,
+ page: RevisionPageDocument
+): { previous?: RevisionPageDocument; next?: RevisionPageDocument } {
+ const flat = flattenPages(revision.pages);
+
+ const currentIndex = flat.findIndex((p) => p.id === page.id);
+ if (currentIndex === -1) {
+ return {};
+ }
+
+ const previous = flat[currentIndex - 1];
+ const next = flat[currentIndex + 1];
+
+ return {
+ previous, next
+ };
+}
+
+
function resolveFirstDocument(
pages: RevisionPage[],
ancestors: AncestorRevisionPage[],
@@ -105,3 +128,19 @@ function resolvePageDocument(
return { page, ancestors };
}
+
+function flattenPages(pages: RevisionPage[]): RevisionPageDocument[] {
+ const result: RevisionPageDocument[] = [];
+ for (const page of pages) {
+ if (page.type === 'link') {
+ continue;
+ }
+
+ if (page.type === 'document') {
+ result.push(page);
+ }
+ result.push(...flattenPages(page.pages));
+ }
+
+ return result;
+}