diff --git a/src/app/classroom/layout.tsx b/src/app/classroom/layout.tsx
new file mode 100644
index 0000000..dcdb29e
--- /dev/null
+++ b/src/app/classroom/layout.tsx
@@ -0,0 +1,8 @@
+import type { Metadata } from "next";
+
+// A church's parent take-home page: rendered in the browser with a generic title, and it repeats lessons that have their own pages.
+export const metadata: Metadata = { robots: { index: false, follow: true } };
+
+export default function Layout({ children }: { children: React.ReactNode }) {
+ return children;
+}
diff --git a/src/app/external/layout.tsx b/src/app/external/layout.tsx
new file mode 100644
index 0000000..87f6d2f
--- /dev/null
+++ b/src/app/external/layout.tsx
@@ -0,0 +1,8 @@
+import type { Metadata } from "next";
+
+// Another provider's curriculum shown through Lessons.church: rendered in the browser with a generic title, and the content belongs to that provider.
+export const metadata: Metadata = { robots: { index: false, follow: true } };
+
+export default function Layout({ children }: { children: React.ReactNode }) {
+ return children;
+}
diff --git a/tests/seo.spec.ts b/tests/seo.spec.ts
index 527bd9c..ba5ee65 100644
--- a/tests/seo.spec.ts
+++ b/tests/seo.spec.ts
@@ -78,6 +78,14 @@ test.describe("SEO", () => {
});
}
+ // Both render only in the browser behind a generic title; their lessons are indexed on their own pages.
+ for (const path of ["/classroom/CLS00000001", "/external/provider/program"]) {
+ test(`${path} is noindex`, async ({ request }) => {
+ const html = await (await request.get(path)).text();
+ expect(html).toMatch(/ {
const html = await (await request.get("/search?q=noah")).text();
expect(html).toMatch(/