diff --git a/package-lock.json b/package-lock.json index ab9525c..f5ed95c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -39,6 +39,7 @@ "@radix-ui/react-toggle-group": "^1.1.0", "@radix-ui/react-tooltip": "^1.1.4", "@tanstack/react-query": "^5.56.2", + "@unhead/react": "^2.0.10", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "cmdk": "^1.0.0", @@ -3625,6 +3626,21 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@unhead/react": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@unhead/react/-/react-2.0.10.tgz", + "integrity": "sha512-U5tqhUYk4qmyLD8YpKOuYwWmbIGFpB7aacOzcGAhjJ59GH3W/BSFOFHj/6dcoYV5yzr1CZrINGGH7stRVMMLjQ==", + "license": "MIT", + "dependencies": { + "unhead": "2.0.10" + }, + "funding": { + "url": "https://github.com/sponsors/harlan-zw" + }, + "peerDependencies": { + "react": ">=18" + } + }, "node_modules/@vitejs/plugin-react-swc": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/@vitejs/plugin-react-swc/-/plugin-react-swc-3.9.0.tgz", @@ -5129,6 +5145,12 @@ "node": ">= 0.4" } }, + "node_modules/hookable": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz", + "integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==", + "license": "MIT" + }, "node_modules/html-encoding-sniffer": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", @@ -7197,6 +7219,18 @@ "dev": true, "license": "MIT" }, + "node_modules/unhead": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/unhead/-/unhead-2.0.10.tgz", + "integrity": "sha512-GT188rzTCeSKt55tYyQlHHKfUTtZvgubrXiwzGeXg6UjcKO3FsagaMzQp6TVDrpDY++3i7Qt0t3pnCc/ebg5yQ==", + "license": "MIT", + "dependencies": { + "hookable": "^5.5.3" + }, + "funding": { + "url": "https://github.com/sponsors/harlan-zw" + } + }, "node_modules/update-browserslist-db": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", diff --git a/package.json b/package.json index 47f22ff..b536d77 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,7 @@ "@radix-ui/react-toggle-group": "^1.1.0", "@radix-ui/react-tooltip": "^1.1.4", "@tanstack/react-query": "^5.56.2", + "@unhead/react": "^2.0.10", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "cmdk": "^1.0.0", diff --git a/src/App.tsx b/src/App.tsx index 09bcfa5..99471bf 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,17 +1,20 @@ // NOTE: This file should normally not be modified unless you are adding a new provider. // To add new routes, edit the AppRouter.tsx file. +import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; +import { createHead, UnheadProvider } from '@unhead/react/client'; import { Suspense } from 'react'; -import NostrProvider from '@/components/NostrProvider' +import NostrProvider from '@/components/NostrProvider'; import { Toaster } from "@/components/ui/toaster"; import { Toaster as Sonner } from "@/components/ui/sonner"; import { TooltipProvider } from "@/components/ui/tooltip"; -import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { NostrLoginProvider } from '@nostrify/react/login'; import { AppProvider } from '@/components/AppProvider'; import { AppConfig } from '@/contexts/AppContext'; import AppRouter from './AppRouter'; +const head = createHead(); + const queryClient = new QueryClient({ defaultOptions: { queries: { @@ -36,21 +39,23 @@ const presetRelays = [ export function App() { return ( - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + ); } diff --git a/src/pages/Index.tsx b/src/pages/Index.tsx index 4c131e5..4427de5 100644 --- a/src/pages/Index.tsx +++ b/src/pages/Index.tsx @@ -1,6 +1,13 @@ +import { useSeoMeta } from '@unhead/react'; + // FIXME: Update this page (the content is just a fallback if you fail to update the page) const Index = () => { + useSeoMeta({ + title: 'Welcome to Your Blank App', + description: 'A modern Nostr client application built with React, TailwindCSS, and Nostrify.', + }); + return (
diff --git a/src/pages/NotFound.tsx b/src/pages/NotFound.tsx index c970104..85e429d 100644 --- a/src/pages/NotFound.tsx +++ b/src/pages/NotFound.tsx @@ -1,9 +1,15 @@ +import { useSeoMeta } from "@unhead/react"; import { useLocation } from "react-router-dom"; import { useEffect } from "react"; const NotFound = () => { const location = useLocation(); + useSeoMeta({ + title: "404 - Page Not Found", + description: "The page you are looking for could not be found. Return to the home page to continue browsing.", + }); + useEffect(() => { console.error( "404 Error: User attempted to access non-existent route:", diff --git a/src/test/TestApp.tsx b/src/test/TestApp.tsx index ba48ba6..ba46d95 100644 --- a/src/test/TestApp.tsx +++ b/src/test/TestApp.tsx @@ -1,5 +1,6 @@ -import { BrowserRouter } from 'react-router-dom'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import { createHead, UnheadProvider } from '@unhead/react/client'; +import { BrowserRouter } from 'react-router-dom'; import { NostrLoginProvider } from '@nostrify/react/login'; import NostrProvider from '@/components/NostrProvider'; import { AppProvider } from '@/components/AppProvider'; @@ -10,6 +11,8 @@ interface TestAppProps { } export function TestApp({ children }: TestAppProps) { + const head = createHead(); + const queryClient = new QueryClient({ defaultOptions: { queries: { retry: false }, @@ -23,17 +26,19 @@ export function TestApp({ children }: TestAppProps) { }; return ( - + - {children} + + {children} + - + ); }