Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
6e35914
Added the new docs homepage with sidenav
Debanitrkl Dec 14, 2025
9384e7b
Added the ingestion flow
Debanitrkl Dec 16, 2025
d025c30
Added the copy page integration
Debanitrkl Dec 17, 2025
68c10df
Fixed the failure
Debanitrkl Dec 17, 2025
cf944d4
Fixed the telemetry router
Debanitrkl Dec 17, 2025
9321f83
Revamped the side nav
Debanitrkl Dec 18, 2025
cc85e65
Added integrations
Debanitrkl Dec 18, 2025
1e2c4be
Added datadog like integrations page
Debanitrkl Dec 18, 2025
5eccdca
Added AI based search
Debanitrkl Dec 19, 2025
0dff14e
updated the side-nav for integrations
Debanitrkl Dec 19, 2025
3ae1dc0
Added the docs and added executable blocks
Debanitrkl Dec 19, 2025
12d2b58
Added security guardrails
Debanitrkl Dec 19, 2025
f1f3542
Updated features and user-guide
Debanitrkl Dec 22, 2025
f329a08
Fix ESLint errors
Debanitrkl Dec 22, 2025
3e1c70f
Added examples for prometheus
Debanitrkl Dec 22, 2025
6789e1d
Updated the sidenav structure
Debanitrkl Dec 22, 2025
4332f86
Added homepage content in root path
Debanitrkl Dec 22, 2025
7004f11
Fixed URL redirects
Debanitrkl Dec 22, 2025
6e76300
Fix mainPage.tsx JSX syntax errors
Debanitrkl Dec 22, 2025
ac78542
fix: Remove 404 links from documentation_pages.csv
Debanitrkl Dec 29, 2025
f581378
feat: add Ask AI chat, deployment mode switcher, and LLM endpoints
Debanitrkl Dec 31, 2025
1e7b1c1
fix: remove conflicting /docs/* redirect that breaks production deplo…
Debanitrkl Dec 31, 2025
8d360c3
fix: revert to assetPrefix instead of basePath to match main branch
Debanitrkl Dec 31, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
5 changes: 4 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,7 @@ NEXT_PUBLIC_GA_MEASUREMENT_ID=G-XXXXXXXXXX
NEXT_PUBLIC_ENV=development/production

# Koala Analytics
NEXT_PUBLIC_KOALA_PUBLIC_API_KEY=pk_xxxxxxxxxxxxxxxxxxxxxxxx
NEXT_PUBLIC_KOALA_PUBLIC_API_KEY=pk_xxxxxxxxxxxxxxxxxxxxxxxx

# Tavily AI Search API Key (get from https://tavily.com)
TAVILY_API_KEY=tvly-XXXXXXXXXX
13 changes: 13 additions & 0 deletions .source/browser.ts

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions .source/dynamic.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// @ts-nocheck
import { dynamic } from 'fumadocs-mdx/runtime/dynamic';
import * as Config from '../source.config';

const create = await dynamic<typeof Config, import("fumadocs-mdx/runtime/types").InternalTypeConfig & {
DocData: {
}
}>(Config, {"configPath":"source.config.ts","environment":"next","outDir":".source"}, {"doc":{"passthroughs":["extractedReferences"]}});
942 changes: 0 additions & 942 deletions .source/index.ts

This file was deleted.

287 changes: 287 additions & 0 deletions .source/server.ts

Large diffs are not rendered by default.

43 changes: 43 additions & 0 deletions .source/source.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// source.config.ts
import {
defineConfig,
defineDocs,
frontmatterSchema,
metaSchema
} from "fumadocs-mdx/config";
import { remarkAdmonition } from "fumadocs-core/mdx-plugins";
var docs = defineDocs({
// The root directory for all documentation
dir: "content/docs",
docs: {
schema: frontmatterSchema,
postprocess: {
// Only include processed markdown in production (for LLM endpoints)
includeProcessedMarkdown: process.env.NODE_ENV === "production"
}
},
meta: {
schema: metaSchema
}
});
var releaseNotes = defineDocs({
// The root directory for release notes
dir: "content/release-notes",
docs: {
schema: frontmatterSchema
},
meta: {
schema: metaSchema
}
});
var source_config_default = defineConfig({
mdxOptions: {
remarkPlugins: [remarkAdmonition],
rehypePlugins: []
}
});
export {
source_config_default as default,
docs,
releaseNotes
};
25 changes: 15 additions & 10 deletions app/(docs)/[[...slug]]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,7 @@ import {
import { notFound } from 'next/navigation';
import { createRelativeLink } from 'fumadocs-ui/mdx';
import { getMDXComponents } from '@/mdx-components';
import { EditOnGitHub } from './page.client';

const owner = 'parseablehq';
const repo = 'developer-hub';
import { CopyPageDropdown } from '@/components/CopyPageDropdown';

import { HomepageContent } from './homepage.client';

Expand All @@ -28,19 +25,18 @@ export default async function Page(props: {
// Otherwise, show the regular docs page
const page = source.getPage(params.slug);
if (!page) notFound();
const path = `content/docs/${page.file.path}`;

const MDXContent = page.data.body;

return (
<DocsPage toc={page.data.toc} full={page.data.full}>
<DocsPage
toc={page.data.toc}
full={page.data.full}
>
<DocsTitle>{page.data.title}</DocsTitle>
<DocsDescription>{page.data.description}</DocsDescription>
<div className="flex flex-row gap-2 items-center mb-4">
{/* <LLMCopyButton slug={params.slug} /> */}
<EditOnGitHub
url={`https://github.com/${owner}/${repo}/tree/main/${path}`}
/>
<CopyPageDropdown slug={params.slug} filePath={`${params.slug?.join('/') || 'index'}.mdx`} />
</div>
<hr/>
<DocsBody>
Expand All @@ -65,6 +61,15 @@ export async function generateMetadata(props: {
params: Promise<{ slug?: string[] }>;
}) {
const params = await props.params;

// Handle root /docs path
if (!params.slug || params.slug.length === 0) {
return {
title: 'Documentation | Parseable',
description: 'Parseable documentation and guides',
};
}

const page = source.getPage(params.slug);
if (!page) notFound();

Expand Down
16 changes: 13 additions & 3 deletions app/(docs)/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,27 @@ import { DocsLayout } from 'fumadocs-ui/layouts/docs';
import type { ReactNode } from 'react';
import { baseOptions } from '@/app/layout.config';
import { source } from '@/lib/source';
import SearchButton from '@/components/SearchButton';
import { AskAITrigger } from '@/components/AskAI';
import { SidebarBanner } from '@/components/SidebarBanner';

export default function Layout({ children }: { children: ReactNode }) {
return (
<DocsLayout
tree={source.pageTree}
{...baseOptions}
// sidebar={{
// enabled: false
// }}
searchToggle={{
components: {
sm: <SearchButton />,
lg: <SearchButton />,
},
}}
sidebar={{
banner: <SidebarBanner />,
}}
>
{children}
<AskAITrigger />
</DocsLayout>
);
}
71 changes: 71 additions & 0 deletions app/api/ai-search/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { NextRequest, NextResponse } from 'next/server';

export async function POST(request: NextRequest) {
try {
const { query } = await request.json();

if (!query || typeof query !== 'string') {
return NextResponse.json(
{ error: 'Query is required' },
{ status: 400 }
);
}

const apiKey = process.env.TAVILY_API_KEY;
if (!apiKey) {
return NextResponse.json(
{ error: 'Tavily API key not configured' },
{ status: 500 }
);
}

// Search specifically within Parseable documentation
const response = await fetch('https://api.tavily.com/search', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
api_key: apiKey,
query: `${query} site:parseable.com OR site:parseable.io`,
search_depth: 'advanced',
include_answer: true,
include_raw_content: false,
max_results: 5,
include_domains: ['parseable.com', 'parseable.io', 'docs.parseable.com'],
}),
});

if (!response.ok) {
const errorText = await response.text();
console.error('Tavily API error:', errorText);
return NextResponse.json(
{ error: 'Failed to fetch AI search results' },
{ status: response.status }
);
}

const data = await response.json();

return NextResponse.json({
answer: data.answer || null,
results: data.results?.map((result: {
title: string;
url: string;
content: string;
score?: number;
}) => ({
title: result.title,
url: result.url,
content: result.content,
score: result.score,
})) || [],
});
} catch (error) {
console.error('AI search error:', error);
return NextResponse.json(
{ error: 'Internal server error' },
{ status: 500 }
);
}
}
Loading