Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/fix-next-version-resolution.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@workflow/next": patch
---

Fix `next/package.json` resolution failure in npm workspaces monorepos
2 changes: 1 addition & 1 deletion .github/actions/prepare-workbench-path/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ runs:
- id: prepare
shell: bash
run: |
if [[ "${{ inputs.app-name }}" == "nextjs-turbopack" || "${{ inputs.app-name }}" == "nextjs-webpack" ]]; then
if [[ "${{ inputs.app-name }}" == "nextjs-turbopack" || "${{ inputs.app-name }}" == "nextjs-webpack" || "${{ inputs.app-name }}" == "nextjs-eager" ]]; then
STAGE_LOG="$(mktemp)"
node scripts/stage-workbench-with-tarballs.mjs "workbench/${{ inputs.app-name }}" | tee "$STAGE_LOG"
WORKBENCH_APP_PATH="$(sed -n 's/^Staged workbench: //p' "$STAGE_LOG" | tail -n 1)"
Expand Down
2 changes: 1 addition & 1 deletion .github/scripts/generate-docs-data.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ function parseE2EResults(files) {
// Extract framework from filename for detailed breakdown
const basename = path.basename(file, '.json');
const frameworkMatch = basename.match(
/-(nextjs-turbopack|nextjs-webpack|nitro|nuxt|sveltekit|vite|hono|express|fastify|astro)(?:-(canary|stable))?$/
/-(nextjs-turbopack|nextjs-webpack|nextjs-eager|nitro|nuxt|sveltekit|vite|hono|express|fastify|astro)(?:-(canary|stable))?$/
);
if (frameworkMatch) {
const framework = frameworkMatch[1];
Expand Down
132 changes: 132 additions & 0 deletions docs/app/[lang]/cookbook/[[...slug]]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import { Step, Steps } from 'fumadocs-ui/components/steps';
import { Tab, Tabs } from 'fumadocs-ui/components/tabs';
import { createRelativeLink } from 'fumadocs-ui/mdx';
import type { Metadata } from 'next';
import { notFound } from 'next/navigation';
import type { ComponentProps } from 'react';
import {
rewriteCookbookUrl,
rewriteCookbookUrlsInText,
} from '@/lib/geistdocs/cookbook-source';
import { AskAI } from '@/components/geistdocs/ask-ai';
import { CopyPage } from '@/components/geistdocs/copy-page';
import {
DocsBody,
DocsDescription,
DocsPage,
DocsTitle,
} from '@/components/geistdocs/docs-page';
import { EditSource } from '@/components/geistdocs/edit-source';
import { Feedback } from '@/components/geistdocs/feedback';
import { getMDXComponents } from '@/components/geistdocs/mdx-components';
import { OpenInChat } from '@/components/geistdocs/open-in-chat';
import { ScrollTop } from '@/components/geistdocs/scroll-top';
import { Badge } from '@/components/ui/badge';
import { Separator } from '@/components/ui/separator';
import { getLLMText, getPageImage, source } from '@/lib/geistdocs/source';

const Page = async ({ params }: PageProps<'/[lang]/cookbook/[[...slug]]'>) => {
const { slug, lang } = await params;

// Prepend 'cookbook' to resolve from the docs source
const resolvedSlug = slug ? ['cookbook', ...slug] : ['cookbook'];
const page = source.getPage(resolvedSlug, lang);

if (!page) {
notFound();
}

const publicUrl = rewriteCookbookUrl(page.url);
const publicPage = { ...page, url: publicUrl } as typeof page;

const markdown = rewriteCookbookUrlsInText(await getLLMText(page));
const MDX = page.data.body;

const RelativeLink = createRelativeLink(source, publicPage);
const PublicCookbookLink = (props: ComponentProps<typeof RelativeLink>) => {
const href =
typeof props.href === 'string'
? rewriteCookbookUrl(props.href)
: props.href;
return <RelativeLink {...props} href={href} />;
};

return (
<DocsPage
full={page.data.full}
tableOfContent={{
style: 'clerk',
footer: (
<div className="my-3 space-y-3">
<Separator />
<EditSource path={page.path} />
<ScrollTop />
<Feedback />
<CopyPage text={markdown} />
<AskAI href={publicUrl} />
<OpenInChat href={publicUrl} />
</div>
),
}}
toc={page.data.toc}
>
<DocsTitle>{page.data.title}</DocsTitle>
<DocsDescription>{page.data.description}</DocsDescription>
<DocsBody>
<MDX
components={getMDXComponents({
a: PublicCookbookLink,
Badge,
Step,
Steps,
Tabs,
Tab,
})}
/>
</DocsBody>
</DocsPage>
);
};

export const generateStaticParams = () => {
// Generate params for all cookbook pages
const allParams = source.generateParams();
return allParams
.filter((p) => Array.isArray(p.slug) && p.slug[0] === 'cookbook')
.map((p) => ({
...p,
slug: (p.slug as string[]).slice(1), // Remove 'cookbook' prefix
}));
};

export const generateMetadata = async ({
params,
}: PageProps<'/[lang]/cookbook/[[...slug]]'>) => {
const { slug, lang } = await params;
const resolvedSlug = slug ? ['cookbook', ...slug] : ['cookbook'];
const page = source.getPage(resolvedSlug, lang);

if (!page) {
notFound();
}

const publicPath = rewriteCookbookUrl(page.url);

const metadata: Metadata = {
title: page.data.title,
description: page.data.description,
openGraph: {
images: getPageImage(page).url,
},
alternates: {
canonical: publicPath,
types: {
'text/markdown': `${publicPath}.md`,
},
},
};

return metadata;
};

export default Page;
13 changes: 13 additions & 0 deletions docs/app/[lang]/cookbook/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { DocsLayout } from '@/components/geistdocs/docs-layout';
import { getCookbookTree } from '@/lib/geistdocs/cookbook-source';

const Layout = async ({
children,
params,
}: LayoutProps<'/[lang]/cookbook'>) => {
const { lang } = await params;

return <DocsLayout tree={getCookbookTree(lang)}>{children}</DocsLayout>;
};

export default Layout;
17 changes: 15 additions & 2 deletions docs/app/[lang]/docs/[[...slug]]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import { Step, Steps } from 'fumadocs-ui/components/steps';
import { Tab, Tabs } from 'fumadocs-ui/components/tabs';
import { createRelativeLink } from 'fumadocs-ui/mdx';
import type { Metadata } from 'next';
import { notFound } from 'next/navigation';
import { notFound, permanentRedirect } from 'next/navigation';
import { rewriteCookbookUrl } from '@/lib/geistdocs/cookbook-source';
import { AgentTraces } from '@/components/custom/agent-traces';
import { FluidComputeCallout } from '@/components/custom/fluid-compute-callout';
import { AskAI } from '@/components/geistdocs/ask-ai';
Expand Down Expand Up @@ -31,6 +32,12 @@ const WorldTestingPerformanceNoop = () => null;
const Page = async ({ params }: PageProps<'/[lang]/docs/[[...slug]]'>) => {
const { slug, lang } = await params;

if (Array.isArray(slug) && slug[0] === 'cookbook') {
const rest = slug.slice(1).join('/');
const legacyPath = `/docs/cookbook${rest ? `/${rest}` : ''}`;
permanentRedirect(`/${lang}${rewriteCookbookUrl(legacyPath)}`);
}

const page = source.getPage(slug, lang);

if (!page) {
Expand Down Expand Up @@ -85,7 +92,13 @@ const Page = async ({ params }: PageProps<'/[lang]/docs/[[...slug]]'>) => {
);
};

export const generateStaticParams = () => source.generateParams();
export const generateStaticParams = () =>
source
.generateParams()
.filter(
(params) =>
!(Array.isArray(params.slug) && params.slug[0] === 'cookbook'),
);

export const generateMetadata = async ({
params,
Expand Down
8 changes: 6 additions & 2 deletions docs/app/[lang]/docs/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import { DocsLayout } from '@/components/geistdocs/docs-layout';
import { source } from '@/lib/geistdocs/source';
import { getDocsTreeWithoutCookbook } from '@/lib/geistdocs/cookbook-source';

const Layout = async ({ children, params }: LayoutProps<'/[lang]/docs'>) => {
const { lang } = await params;

return <DocsLayout tree={source.pageTree[lang]}>{children}</DocsLayout>;
return (
<DocsLayout tree={getDocsTreeWithoutCookbook(lang)}>
{children}
</DocsLayout>
);
};

export default Layout;
2 changes: 1 addition & 1 deletion docs/app/[lang]/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const Layout = async ({ children, params }: LayoutProps<'/[lang]'>) => {

return (
<html
className={cn(sans.variable, mono.variable, 'scroll-smooth antialiased')}
className={cn(sans.variable, mono.variable, 'antialiased')}
lang={lang}
suppressHydrationWarning
>
Expand Down
5 changes: 4 additions & 1 deletion docs/app/[lang]/llms.mdx/[[...slug]]/route.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { notFound } from 'next/navigation';
import { rewriteCookbookUrlsInText } from '@/lib/geistdocs/cookbook-source';
import { getLLMText, source } from '@/lib/geistdocs/source';
import { i18n } from '@/lib/geistdocs/i18n';

Expand All @@ -18,8 +19,10 @@ export async function GET(
const sitemapPath =
lang === i18n.defaultLanguage ? '/sitemap.md' : `/${lang}/sitemap.md`;

const text = await getLLMText(page);

return new Response(
(await getLLMText(page)) +
rewriteCookbookUrlsInText(text) +
`\n\n## Sitemap
[Overview of all docs pages](${sitemapPath})\n`,
{
Expand Down
3 changes: 2 additions & 1 deletion docs/app/[lang]/llms.txt/route.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { NextRequest } from 'next/server';
import { rewriteCookbookUrlsInText } from '@/lib/geistdocs/cookbook-source';
import { getLLMText, source } from '@/lib/geistdocs/source';

export const revalidate = false;
Expand All @@ -11,7 +12,7 @@ export const GET = async (
const scan = source.getPages(lang).map(getLLMText);
const scanned = await Promise.all(scan);

return new Response(scanned.join('\n\n'), {
return new Response(rewriteCookbookUrlsInText(scanned.join('\n\n')), {
headers: {
'Content-Type': 'text/markdown; charset=utf-8',
},
Expand Down
6 changes: 3 additions & 3 deletions docs/app/[lang]/sitemap.md/route.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { Node, Root } from 'fumadocs-core/page-tree';
import { rewriteCookbookUrl } from '@/lib/geistdocs/cookbook-source';
import { source } from '@/lib/geistdocs/source';

export const revalidate = false;
Expand All @@ -16,10 +17,10 @@ export async function GET(

if ('type' in node) {
if (node.type === 'page') {
mdText += `${indent}- [${node.name}](${node.url})\n`;
mdText += `${indent}- [${node.name}](${rewriteCookbookUrl(node.url)})\n`;
} else if (node.type === 'folder') {
if (node.index) {
mdText += `${indent}- [${node.name}](${node.index.url})\n`;
mdText += `${indent}- [${node.name}](${rewriteCookbookUrl(node.index.url)})\n`;
} else {
mdText += `${indent}- ${node.name}\n`;
}
Expand All @@ -30,7 +31,6 @@ export async function GET(
}
}
} else if (node.children.length > 0) {
// Root node
for (const child of node.children) {
traverseTree(child, depth);
}
Expand Down
6 changes: 3 additions & 3 deletions docs/app/sitemap.md/route.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { Node, Root } from 'fumadocs-core/page-tree';
import { rewriteCookbookUrl } from '@/lib/geistdocs/cookbook-source';
import { i18n } from '@/lib/geistdocs/i18n';
import { source } from '@/lib/geistdocs/source';

Expand All @@ -13,10 +14,10 @@ export async function GET(_req: Request) {

if ('type' in node) {
if (node.type === 'page') {
mdText += `${indent}- [${node.name}](${node.url})\n`;
mdText += `${indent}- [${node.name}](${rewriteCookbookUrl(node.url)})\n`;
} else if (node.type === 'folder') {
if (node.index) {
mdText += `${indent}- [${node.name}](${node.index.url})\n`;
mdText += `${indent}- [${node.name}](${rewriteCookbookUrl(node.index.url)})\n`;
} else {
mdText += `${indent}- ${node.name}\n`;
}
Expand All @@ -27,7 +28,6 @@ export async function GET(_req: Request) {
}
}
} else if (node.children.length > 0) {
// Root node
for (const child of node.children) {
traverseTree(child, depth);
}
Expand Down
3 changes: 2 additions & 1 deletion docs/app/sitemap.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { MetadataRoute } from 'next';

import { rewriteCookbookUrl } from '@/lib/geistdocs/cookbook-source';
import { source } from '@/lib/geistdocs/source';

const protocol = process.env.NODE_ENV === 'production' ? 'https' : 'http';
Expand All @@ -17,7 +18,7 @@ export default function sitemap(): MetadataRoute.Sitemap {
changeFrequency: 'weekly' as const,
lastModified: undefined,
priority: 0.5,
url: url(page.url),
url: url(rewriteCookbookUrl(page.url)),
});
}

Expand Down
Loading
Loading