@adpharm/docsafe-search
v2.3.2
Published
A plug-and-play React component library for integrating DocSafe's AI-powered vector search and PDF citation highlighting directly into your application.
Readme
@adpharm/docsafe-search
A plug-and-play React component library and backend utility for integrating DocSafe's AI-powered vector search and PDF citation highlighting directly into your application.
This package uses a "Dumb UI, Smart Server" architecture. It provides beautiful React components for your frontend and a secure search utility for your backend, ensuring your API keys are never exposed to the browser.
Installation
npm install @adpharm/docsafe-search
# or
bun add @adpharm/docsafe-search1. Prerequisites (Environment Variables)
Your host application's backend must have the following environment variables set:
OPENAI_API_KEY=your_openai_key
DOCSAFE_API_KEY=your_docsafe_db_key
# DOCSAFE_DB_URL=https://db.docsafe-search.adpharm.digital (Optional: defaults to production)2. Styling
Import the stylesheet once, anywhere in your app's entry (e.g. app/layout.tsx in Next.js, main.tsx in Vite, or your root entry file):
import "@adpharm/docsafe-search/styles.css";That's it. No Tailwind configuration, no wrapper components, no @source directives. The package ships all its styles self-contained under a ds-* namespace that cannot collide with your app's classes. It also works whether or not the host application uses Tailwind.
3. Backend Implementation
Create an API route in your host application to securely handle the vector search and LLM generation.
Example (Next.js App Router - app/api/search/route.ts):
import { runDocSafeSearch } from "@adpharm/docsafe-search/server";
export async function POST(req: Request) {
try {
const { query, projectId } = await req.json();
// This utility automatically reads your .env variables, performs the vector
// search, and asks OpenAI to generate an answer with citations.
const searchResults = await runDocSafeSearch(query, projectId);
return Response.json(searchResults);
} catch (error: any) {
return Response.json({ error: error.message }, { status: 500 });
}
}4. Frontend Implementation
Use the exported UI components to build your search interface.
Example (React / Next.js Client Component):
"use client";
import { useState } from "react";
import {
SearchBar,
ResultsPage,
SearchResultData,
} from "@adpharm/docsafe-search";
export default function DocumentSearch() {
const [data, setData] = useState<SearchResultData | null>(null);
const [isLoading, setIsLoading] = useState(false);
const [query, setQuery] = useState("");
const [error, setError] = useState<string>();
const handleSearch = async (searchQuery: string, projectId: string) => {
setIsLoading(true);
setQuery(searchQuery);
setError(undefined);
try {
// Call your secure backend route
const response = await fetch("/api/search", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ query: searchQuery, projectId }),
});
if (!response.ok) throw new Error("Search failed");
const resultData = await response.json();
setData(resultData);
} catch (err: any) {
setError(err.message);
} finally {
setIsLoading(false);
}
};
// If we have data (or are loading data), show the Results layout
if (data || isLoading) {
return (
<ResultsPage
query={query}
isLoading={isLoading}
data={data}
error={error}
/>
);
}
// Otherwise, show the initial Search Bar
return (
<div className="flex items-center justify-center min-h-screen p-8">
<div className="w-full max-w-3xl">
<h1 className="text-3xl font-bold mb-8 text-center">
Search Clinical Guidelines
</h1>
<SearchBar projectId="your-project-uuid-here" onSearch={handleSearch} />
</div>
</div>
);
}