import { useStore } from '@nanostores/react'; import type { LinksFunction } from '@remix-run/cloudflare'; import { Links, Meta, Outlet, Scripts, ScrollRestoration, useLocation } from '@remix-run/react'; import tailwindReset from '@unocss/reset/tailwind-compat.css?url'; import { useEffect } from 'react'; import { sendAnalyticsEvent, AnalyticsAction } from './lib/analytics'; import { themeStore } from './lib/stores/theme'; import { stripIndents } from './utils/stripIndent'; import reactToastifyStyles from 'react-toastify/dist/ReactToastify.css?url'; import globalStyles from './styles/index.scss?url'; import xtermStyles from '@xterm/xterm/css/xterm.css?url'; import 'virtual:uno.css'; export const links: LinksFunction = () => [ { rel: 'icon', href: '/favicon.svg', type: 'image/svg+xml', }, { rel: 'stylesheet', href: reactToastifyStyles }, { rel: 'stylesheet', href: tailwindReset }, { rel: 'stylesheet', href: globalStyles }, { rel: 'stylesheet', href: xtermStyles }, { rel: 'preconnect', href: 'https://fonts.googleapis.com', }, { rel: 'preconnect', href: 'https://fonts.gstatic.com', crossOrigin: 'anonymous', }, { rel: 'stylesheet', href: 'https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap', }, ]; const inlineThemeCode = stripIndents` setTutorialKitTheme(); function setTutorialKitTheme() { let theme = localStorage.getItem('bolt_theme'); if (!theme) { theme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'; } document.querySelector('html')?.setAttribute('data-theme', theme); } `; export function Layout({ children }: { children: React.ReactNode }) { const theme = useStore(themeStore); const { pathname } = useLocation(); // log page events when the window location changes useEffect(() => { sendAnalyticsEvent({ action: AnalyticsAction.Page, payload: { properties: { url: window.location.href, }, }, }); }, [pathname]); return (