### Run Next.js Development Server
Source: https://github.com/get-convex/convex-resource-search/blob/main/README.md
Commands to start the Next.js development server. These commands are typically run from the project's root directory and are essential for local development and testing. No specific inputs or outputs are defined beyond the server starting.
```bash
npm run dev
# or
yarn dev
# or
pnpm dev
```
--------------------------------
### Project Package Configuration in JSON
Source: https://context7.com/get-convex/convex-resource-search/llms.txt
The `package.json` file for the project, detailing its name, version, and private status. It includes essential scripts for development (dev, build, start, lint) and lists all project dependencies, including libraries like `react`, `next`, `react-markdown`, and development tools such as `tailwindcss`.
```json
{
"name": "search",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"@radix-ui/react-icons": "^1.3.0",
"@tailwindcss/line-clamp": "^0.4.4",
"@tailwindcss/postcss": "^4.1.11",
"algoliasearch": "^5.0.0",
"classnames": "^2.3.2",
"next": "15.5.6",
"react": "18.3.1",
"react-dom": "18.3.1",
"react-instantsearch": "^7.13.0",
"react-markdown": "^10.0.0",
"tailwindcss": "^4.1.11",
"typescript": "5.9.3"
}
}
```
--------------------------------
### Initialize Algolia Search Client with React InstantSearch
Source: https://context7.com/get-convex/convex-resource-search/llms.txt
Initializes the Algolia search client using provided credentials and integrates it with React InstantSearch for enabling search functionality. This setup is typically done at the root of the application to provide the search client to all child components.
```typescript
'use client';
import Search from '@/components/Search';
import { liteClient } from 'algoliasearch/lite';
import { InstantSearch } from 'react-instantsearch';
// Initialize search client with Algolia credentials
const searchClient = liteClient(
'1KIE511890',
'07096f4c927e372785f8453f177afb16'
);
export default function Home() {
return (
);
}
```
--------------------------------
### Manage Search Query State and URL Sync in React
Source: https://context7.com/get-convex/convex-resource-search/llms.txt
Implements the main search component, managing the search query state, synchronizing it with URL parameters for shareable searches, and rendering search input and results. It uses `react-instantsearch` hooks for search refinement and `URLSearchParams` for URL manipulation.
```typescript
'use client';
import { useSearchBox } from 'react-instantsearch';
import { useEffect, useState } from 'react';
import Results from './Results';
import SearchBox from './SearchBox';
const queryParam = 'q';
export default function Search() {
const { refine } = useSearchBox();
const [query, setQuery] = useState('');
// Handle search input changes
const handleChange = (event: React.ChangeEvent) => {
const value = event.target.value;
setQuery(value);
refine(value);
updateQueryParam(value);
};
// Clear search query
const handleClear = () => {
setQuery('');
refine('');
updateQueryParam('');
};
// Update URL parameter without page reload
const updateQueryParam = (value: string) => {
const urlParams = new URLSearchParams(window.location.search);
if (value) {
urlParams.set(queryParam, value);
} else {
urlParams.delete(queryParam);
}
const baseUrl = `${window.location.origin}${window.location.pathname}`;
const newUrl = urlParams.toString()
? `${baseUrl}?${urlParams.toString()}`
: baseUrl;
window.history.pushState({}, '', newUrl);
};
// Load search query from URL on mount
useEffect(() => {
const urlParams = new URLSearchParams(window.location.search);
const searchParam = urlParams.get(queryParam);
if (searchParam) {
setQuery(searchParam);
refine(searchParam);
}
}, [refine]);
return (
{query === '' ? (
Use the input above to search across Docs, Stack, and Discord.
) : (
)}
);
}
```
--------------------------------
### Next.js Application Layout and Metadata in TypeScript
Source: https://context7.com/get-convex/convex-resource-search/llms.txt
The root layout configuration for a Next.js application. It sets global styles and defines metadata for the application, including the title and description. This file is essential for structuring the application and ensuring consistent metadata across pages.
```typescript
// app/layout.tsx
import './globals.css';
export const metadata = {
title: 'Convex Developer Search',
description: 'Search Docs, Stack, Discord all at once',
};
export default function RootLayout({
children,
}: { children: React.ReactNode }) {
return (
{children}
);
}
```
--------------------------------
### Hit Component: Render Polymorphic Search Results
Source: https://context7.com/get-convex/convex-resource-search/llms.txt
The Hit component renders individual search results, supporting different layouts for Docs, Stack, and Discord hits. It uses conditional rendering based on hit types (isDocsHit, isStackHit, isDiscordHit) and leverages 'react-instantsearch's Highlight component for displaying content. Dependencies include Next.js Image, ImageWithFallback, and a local Markdown component for rendering Discord messages.
```typescript
import Image from 'next/image';
import { Highlight } from 'react-instantsearch';
import ImageWithFallback from './ImageWithFallback';
import Markdown from './Markdown';
import { SearchHit, isDiscordHit, isDocsHit, isStackHit } from './types';
type HitProps = {
hit: SearchHit;
};
export default function Hit({ hit }: HitProps) {
return (
);
}
```
--------------------------------
### HitList Component: Display Search Results
Source: https://context7.com/get-convex/convex-resource-search/llms.txt
The HitList component fetches and displays search results using the `useHits` hook from 'react-instantsearch'. It maps over the hits to render individual `Hit` components and displays a 'No results found.' message if the hits array is empty. It relies on the 'react-instantsearch' library and local 'Hit' and 'types' modules.
```typescript
import { useHits } from 'react-instantsearch';
import Hit from './Hit';
import { SearchHit } from './types';
export default function HitList() {
const { hits } = useHits();
return (
{hits.map((hit) => (
))}
{hits.length === 0 && (
No results found.
)}
);
}
```
--------------------------------
### TypeScript Multi-Index Results Component for Search
Source: https://context7.com/get-convex/convex-resource-search/llms.txt
A React component for displaying search results from multiple Algolia indexes. It features adaptive UI, with tabbed navigation for mobile and a grid layout for desktop. It uses `useState` to manage the currently selected index.
```typescript
import { Index } from 'react-instantsearch';
import HitList from './HitList';
import { useState } from 'react';
import classnames from 'classnames';
const indexes = [
{
name: 'docs',
title: 'Docs',
link: 'https://docs.convex.dev',
},
{
name: 'stack',
title: 'Stack',
link: 'https://stack.convex.dev',
},
{
name: 'discord',
title: 'Discord',
link: 'https://discord.com/invite/nk6C2qTeCq',
},
];
export default function Results() {
const [selectedIndexName, setSelectedIndexName] = useState(indexes[0].name);
return (
);
}
```
--------------------------------
### Image Component with Fallback in TypeScript
Source: https://context7.com/get-convex/convex-resource-search/llms.txt
A client-side image component for Next.js that provides fallback support for broken images. It uses the `next/image` component and manages the image source state. If an image fails to load, it automatically switches to a provided `fallbackSrc`. This component accepts standard `ImageProps` along with a `fallbackSrc`.
```typescript
'use client';
import Image, { ImageProps } from 'next/image';
import { useState } from 'react';
interface ImageWithFallbackProps extends Omit {
src: string;
fallbackSrc: string;
}
export default function ImageWithFallback({
src,
fallbackSrc,
...props
}: ImageWithFallbackProps) {
const [imgSrc, setImgSrc] = useState(src);
const [hasError, setHasError] = useState(false);
const handleError = () => {
if (!hasError) {
setHasError(true);
setImgSrc(fallbackSrc);
}
};
return ;
}
// Usage example
import ImageWithFallback from './ImageWithFallback';
function UserAvatar({ avatarUrl, username }: { avatarUrl: string; username: string }) {
return (
);
}
```
--------------------------------
### TypeScript SearchBox Component with Auto-focus
Source: https://context7.com/get-convex/convex-resource-search/llms.txt
A reusable React SearchBox component that includes automatic input focus on mount and a clear button for resetting the search query. It utilizes `useRef` for direct DOM manipulation and `useEffect` for managing focus.
```typescript
import { Cross2Icon } from '@radix-ui/react-icons';
import { useEffect, useRef } from 'react';
interface SearchBoxProps {
value: string;
onChange: (event: React.ChangeEvent) => void;
onClear: () => void;
}
export default function SearchBox({
value,
onChange,
onClear,
}: SearchBoxProps) {
const inputRef = useRef(null);
const focusInput = () => {
if (inputRef.current) {
inputRef.current.focus();
}
};
const handleClear = () => {
onClear();
focusInput();
};
useEffect(() => {
focusInput();
}, []);
return (
{value !== '' && (
)}
);
}
```
--------------------------------
### TypeScript Type Definitions and Type Guards for Search Hits
Source: https://context7.com/get-convex/convex-resource-search/llms.txt
Defines TypeScript types for different kinds of search results (Docs, Stack, Discord) and provides type guard functions to safely determine the type of a given search hit. This enhances type safety and code clarity when processing search results.
```typescript
export type BaseHit = {
title: string;
objectID: string;
__position: number;
};
export type DocsHit = BaseHit & {
contents: string;
};
export type StackHit = BaseHit & {
summary: string;
content: string;
tags: string[];
};
export type DiscordHit = BaseHit & {
channel: string;
url: string;
date: number;
messages: {
author: {
avatar: string;
convexer: boolean;
name: string;
};
body: string;
}[];
};
export type SearchHit = DocsHit | StackHit | DiscordHit;
// Type guard functions
export function isDocsHit(hit: SearchHit): hit is DocsHit {
return (hit as DocsHit).contents !== undefined;
}
export function isStackHit(hit: SearchHit): hit is StackHit {
return (hit as StackHit).summary !== undefined;
}
export function isDiscordHit(hit: SearchHit): hit is DiscordHit {
return (hit as DiscordHit).messages !== undefined;
}
```
```typescript
// Usage example
import { SearchHit, isDocsHit, isStackHit, isDiscordHit } from './types';
function processHit(hit: SearchHit) {
if (isDocsHit(hit)) {
console.log('Doc contents:', hit.contents);
} else if (isStackHit(hit)) {
console.log('Stack tags:', hit.tags);
} else if (isDiscordHit(hit)) {
console.log('Discord messages:', hit.messages);
}
}
```
--------------------------------
### Markdown Renderer Component in TypeScript
Source: https://context7.com/get-convex/convex-resource-search/llms.txt
A React component that renders markdown content with custom styling for various markdown elements like paragraphs, code blocks, and lists. It utilizes the `react-markdown` library and defines specific CSS classes for enhanced presentation. This component takes a `text` prop which is the markdown string to be rendered.
```typescript
import ReactMarkdown from 'react-markdown';
interface MarkdownProps {
text: string;
}
export default function Markdown({ text }: MarkdownProps) {
return (
(
{children}
),
pre: ({ children }) => (
{children}
),
code: ({ children }) => (
{children}
),
ol: ({ children }) => (
{children}
),
li: ({ children }) => (
{children}
),
}}
>
{text}
);
}
// Usage example
import Markdown from './Markdown';
function DiscordMessage() {
const messageBody = "Here's some **bold** text and `code`:\n```js\nconst x = 1;\n```";
return (
);
}
```
=== COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.