This commit is contained in:
prateek singh 2025-10-13 22:33:21 +05:30 committed by GitHub
commit ad732e4d34
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 77 additions and 3 deletions

View file

@ -3,6 +3,33 @@ import { getBrowseParamsFromPathParam } from "../hooks/utils";
import { CodePreviewPanel } from "./components/codePreviewPanel"; import { CodePreviewPanel } from "./components/codePreviewPanel";
import { Loader2 } from "lucide-react"; import { Loader2 } from "lucide-react";
import { TreePreviewPanel } from "./components/treePreviewPanel"; import { TreePreviewPanel } from "./components/treePreviewPanel";
import { Metadata } from "next";
import { parsePathForTitle} from "@/lib/utils";
type Props = {
params: Promise<{
domain: string;
path: string[];
}>;
};
export async function generateMetadata({ params: paramsPromise }: Props): Promise<Metadata> {
let title = 'Browse'; // Default Fallback
try {
const params = await paramsPromise;
title = parsePathForTitle(params.path);
} catch (error) {
// TODO: Maybe I need to look into a better way of handling this error.
// for now, it is just a log, fallback tab title and prevents the app from crashing.
console.error("Failed to generate metadata title from path:", error);
}
return {
title,
};
}
interface BrowsePageProps { interface BrowsePageProps {
params: Promise<{ params: Promise<{

View file

@ -11,8 +11,14 @@ import { PlanProvider } from "@/features/entitlements/planProvider";
import { getEntitlements } from "@sourcebot/shared"; import { getEntitlements } from "@sourcebot/shared";
export const metadata: Metadata = { export const metadata: Metadata = {
title: "Sourcebot", // Using the title.template will allow child pages to set the title
description: "Sourcebot is a self-hosted code understanding tool. Ask questions about your codebase and get rich Markdown answers with inline citations.", // while keeping a consistent suffix.
title: {
default: "Sourcebot",
template: "%s | Sourcebot",
},
description:
"Sourcebot is a self-hosted code understanding tool. Ask questions about your codebase and get rich Markdown answers with inline citations.",
manifest: "/manifest.json", manifest: "/manifest.json",
}; };

View file

@ -17,6 +17,7 @@ import { ErrorCode } from "./errorCodes";
import { NextRequest } from "next/server"; import { NextRequest } from "next/server";
import { Org } from "@sourcebot/db"; import { Org } from "@sourcebot/db";
import { OrgMetadata, orgMetadataSchema } from "@/types"; import { OrgMetadata, orgMetadataSchema } from "@/types";
import { getBrowseParamsFromPathParam } from "@/app/[domain]/browse/hooks/utils";
export function cn(...inputs: ClassValue[]) { export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs)) return twMerge(clsx(inputs))
@ -487,3 +488,43 @@ export const isHttpError = (error: unknown, status: number): boolean => {
&& 'status' in error && 'status' in error
&& error.status === status; && error.status === status;
} }
/**
* Parses the URL path to generate a descriptive title.
* It handles three cases:
* 1. File view (`blob`): "filename.ts - owner/repo"
* 2. Directory view (`tree`): "directory/ - owner/repo"
* 3. Repository root: "owner/repo"
*
* @param path The array of path segments from Next.js params.
* @returns A formatted title string.
*/
export const parsePathForTitle = (path: string[]): string => {
const pathParam = path.join('/');
const { repoName, revisionName, path: filePath, pathType } = getBrowseParamsFromPathParam(pathParam);
// Build the base repository and revision string.
const cleanRepoName = repoName.split('/').slice(1).join('/'); // Remove the version control system prefix
const repoAndRevision = `${cleanRepoName}${revisionName ? ` @ ${revisionName}` : ''}`;
switch (pathType) {
case 'blob': {
// For blobs, get the filename from the end of the path.
const fileName = filePath.split('/').pop() || filePath;
return `${fileName} - ${repoAndRevision}`;
}
case 'tree': {
// If the path is empty, it's the repo root.
if (filePath === '' || filePath === '/') {
return repoAndRevision;
}
// Otherwise, show the directory path.
const directoryPath = filePath.endsWith('/') ? filePath : `${filePath}/`;
return `${directoryPath} - ${repoAndRevision}`;
}
default:
// Fallback to just the repository name.
return repoAndRevision;
}
}