From 47240e45312895a791b2a3fa1b7574cf9f515551 Mon Sep 17 00:00:00 2001 From: Anthony Ettinger Date: Sat, 31 Oct 2026 07:23:22 +0000 Subject: [PATCH 1/3] fix(footer): use the universal footer --- apps/web/src/app/layout.tsx | 4 +- apps/web/src/components/footer.tsx | 115 +------------------ apps/web/src/components/pit-footer.tsx | 25 ---- apps/web/src/components/universal-footer.tsx | 26 +++++ 4 files changed, 30 insertions(+), 140 deletions(-) delete mode 100644 apps/web/src/components/pit-footer.tsx create mode 100644 apps/web/src/components/universal-footer.tsx diff --git a/apps/web/src/app/layout.tsx b/apps/web/src/app/layout.tsx index 9a1512b7..9a4eef1a 100644 --- a/apps/web/src/app/layout.tsx +++ b/apps/web/src/app/layout.tsx @@ -5,7 +5,7 @@ import { NextIntlClientProvider } from 'next-intl'; import { getLocale, getTranslations } from 'next-intl/server'; import { localeDirection, ogLocale } from '@/i18n/locales'; import { PWAInstallButton } from '@/components/pwa'; -import { PitFooter } from '@/components/pit-footer'; +import { UniversalFooter } from '@/components/universal-footer'; import './globals.css'; export async function generateMetadata(): Promise { @@ -167,7 +167,7 @@ export default async function RootLayout({ children }: { children: React.ReactNo src="https://crawlproof.com/stats.js" strategy="afterInteractive" /> - + ); diff --git a/apps/web/src/components/footer.tsx b/apps/web/src/components/footer.tsx index ff7a6bf4..74e62738 100644 --- a/apps/web/src/components/footer.tsx +++ b/apps/web/src/components/footer.tsx @@ -1,115 +1,4 @@ -import Link from 'next/link'; -import { headers } from 'next/headers'; -import { Footer as PfsFooter } from '@profullstack/footer/react'; -import { useTranslations } from 'next-intl'; -import { Logo } from '@/components/Logo'; -import { LanguageSwitcher } from '@/components/LanguageSwitcher'; - -// Custom GitHub icon SVG component (brand icons deprecated in lucide) -function GitHubIcon({ className }: { className?: string }) { - return ( - - ); -} - -// Custom Twitter/X icon SVG component -function DiscordIcon({ className }: { className?: string }) { - return ( - - ); -} - -function TwitterIcon({ className }: { className?: string }) { - return ( - - ); -} - -// The links people need, one row. Message keys live under footer.links.*. -// The pit.world network footer follows this one (root layout, last in ). -const footerLinks = [ - { key: 'features', href: '/features' }, - { key: 'pricing', href: '/pricing' }, - { key: 'download', href: '/download' }, - { key: 'documentation', href: '/docs' }, - { key: 'blog', href: '/blog' }, - { key: 'about', href: '/about' }, - { key: 'privacy', href: '/privacy' }, - { key: 'terms', href: '/terms' }, -]; - -const socialLinks = [ - { - name: 'GitHub', - href: 'https://github.com/profullstack/pairux.com', - icon: GitHubIcon, - }, - { - name: 'Discord', - href: 'https://discord.gg/U7dEXfBA3s', - icon: DiscordIcon, - }, - { - name: 'X', - href: 'https://x.com/profullstackinc', - icon: TwitterIcon, - }, -]; - -/** - * The ring footer with the request's CSP nonce (middleware sets x-nonce), so the - * newsletter form's inline script (@profullstack/footer 0.4.0) runs under - * script-src 'nonce-...'. - */ -async function RingFooter({ tagline }: { tagline: string }) { - const nonce = (await headers()).get('x-nonce'); - // exactOptionalPropertyTypes: pass nonce only when there is one. - return ; -} - +/** The shared footer is rendered once by the root layout. Keep old page imports harmless. */ export function Footer() { - const t = useTranslations('footer'); - return ( -
-
-
- - -
-
- {socialLinks.map((item) => ( - - {item.name} - - - ))} - -
- {/* Copyright + Profullstack ring, from @profullstack/footer */} - -
-
- ); + return null; } diff --git a/apps/web/src/components/pit-footer.tsx b/apps/web/src/components/pit-footer.tsx deleted file mode 100644 index bc548bc9..00000000 --- a/apps/web/src/components/pit-footer.tsx +++ /dev/null @@ -1,25 +0,0 @@ -// The pit.world network footer, fetched on the server from pit.world and -// cached for an hour. The root layout renders it as the last thing in . -// Any failure (timeout, non-200, network) renders nothing, never a broken page. -// Its inline