Skip to main content
Glama
app.tsx3.55 kB
import { Chat } from "./components/chat"; import { useAuth } from "./contexts/auth-context"; import { useState, useEffect } from "react"; import { Header } from "./components/ui/header"; import { HeaderDivider } from "./components/hero/header-divider"; import { Sidebars } from "./components/home-layout/sidebars"; import HeroBlock from "./components/hero/hero-block"; import UseCases from "./components/usecases"; import GettingStarted from "./components/getting-started"; import TableOfContents from "./components/docs/toc"; import Home from "./pages/home"; import Footer from "./components/home-layout/footer"; export default function App() { const { isAuthenticated, handleLogout } = useAuth(); const [isChatOpen, setIsChatOpen] = useState(() => { // Initialize based on URL query string only to avoid hydration issues const urlParams = new URLSearchParams(window.location.search); const hasQueryParam = urlParams.has("chat"); if (hasQueryParam) { return urlParams.get("chat") !== "0"; } // default to false for mobile and to avoid scroll lock on desktop return false; }); // Adjust initial state for mobile after component mounts useEffect(() => { const urlParams = new URLSearchParams(window.location.search); // Only adjust state if no URL parameter exists and we're on mobile if (!urlParams.has("chat") && window.innerWidth < 768) { setIsChatOpen(false); } }, []); // Update URL when chat state changes const toggleChat = (open: boolean) => { setIsChatOpen(open); if (open) { // Add ?chat to URL const newUrl = new URL(window.location.href); newUrl.searchParams.set("chat", "1"); window.history.pushState({}, "", newUrl.toString()); } else { // Remove query string for home page const newUrl = new URL(window.location.href); newUrl.search = ""; window.history.pushState({}, "", newUrl.toString()); } }; // Handle browser back/forward navigation useEffect(() => { const handlePopState = () => { const urlParams = new URLSearchParams(window.location.search); const hasQueryParam = urlParams.has("chat"); if (hasQueryParam) { setIsChatOpen(urlParams.get("chat") !== "0"); } else { // default to closed on both desktop and mobile setIsChatOpen(false); } }; window.addEventListener("popstate", handlePopState); return () => window.removeEventListener("popstate", handlePopState); }, []); return ( <div className="overflow-x-clip max-w-screen relative"> {/* //!NOTE: order matters for z- */} <Sidebars isChatOpen={isChatOpen} toggleChat={toggleChat} /> <Header toggleChat={toggleChat} isChatOpen={isChatOpen} /> <HeaderDivider /> <HeroBlock /> <UseCases /> <GettingStarted /> {/* main content */} <div className="relative container mx-auto"> <aside className="max-xl:hidden absolute h-full right-15 inset-y-0"> <TableOfContents /> </aside> <main className={`max-w-3xl px-4 sm:px-8 xl:max-w-1/2 mx-auto motion-safe:duration-300 ease-[cubic-bezier(0.25,0.46,0.45,0.94)] ${ isChatOpen ? "xl:-translate-x-1/2" : "" }`} > <Home onChatClick={() => toggleChat(true)} /> </main> </div> <Chat isOpen={isChatOpen} onClose={() => toggleChat(false)} onLogout={handleLogout} /> <Footer isChatOpen={isChatOpen} /> </div> ); }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/getsentry/sentry-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server