diff --git a/.changeset/every-badgers-bake.md b/.changeset/every-badgers-bake.md new file mode 100644 index 00000000000..40b216079f5 --- /dev/null +++ b/.changeset/every-badgers-bake.md @@ -0,0 +1,5 @@ +--- +'@qwik.dev/router': minor +--- + +FEAT: useQwikRouter() hook replaces QwikRouterProvider. This gives access to the context immediately and is slightly more efficient. diff --git a/e2e/adapters-e2e/src/components/router-head/router-head.tsx b/e2e/adapters-e2e/src/components/router-head/router-head.tsx deleted file mode 100644 index 849545cf345..00000000000 --- a/e2e/adapters-e2e/src/components/router-head/router-head.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import { component$ } from '@qwik.dev/core'; -import { useDocumentHead, useLocation } from '@qwik.dev/router'; - -export const RouterHead = component$(() => { - const head = useDocumentHead(); - const loc = useLocation(); - - return ( - <> - {head.title} - - - - - {head.meta.map((m) => ( - - ))} - - {head.links.map((l) => ( - - ))} - - ); -}); diff --git a/e2e/adapters-e2e/src/root.tsx b/e2e/adapters-e2e/src/root.tsx index 505af2e5942..80f7927bb24 100644 --- a/e2e/adapters-e2e/src/root.tsx +++ b/e2e/adapters-e2e/src/root.tsx @@ -1,24 +1,24 @@ import { component$ } from '@qwik.dev/core'; -import { QwikRouterProvider, RouterOutlet } from '@qwik.dev/router'; -import { RouterHead } from './components/router-head/router-head'; +import { DocumentHeadTags, RouterOutlet, useLocation, useQwikRouter } from '@qwik.dev/router'; export default component$(() => { - /** - * The root of a QwikCity site always start with the component, immediately - * followed by the document's and . - * - * Don't remove the `` and `` elements. - */ + useQwikRouter(); + + const loc = useLocation(); return ( - + <> - + + + + + - + - + ); }); diff --git a/packages/docs/src/root.tsx b/packages/docs/src/root.tsx index 85f1643124c..a93c1d9ec97 100644 --- a/packages/docs/src/root.tsx +++ b/packages/docs/src/root.tsx @@ -1,11 +1,19 @@ import { component$, useContextProvider, useStore } from '@qwik.dev/core'; import { Insights } from '@qwik.dev/core/insights'; -import { QwikRouterProvider, RouterOutlet, ServiceWorkerRegister } from '@qwik.dev/router'; +import { + RouterOutlet, + ServiceWorkerRegister, + useDocumentHead, + useLocation, + useQwikRouter, +} from '@qwik.dev/router'; import RealMetricsOptimization from './components/real-metrics-optimization/real-metrics-optimization'; -import { RouterHead } from './components/router-head/router-head'; import { BUILDER_PUBLIC_API_KEY } from './constants'; import { GlobalStore, type SiteStore } from './context'; import './global.css'; +import { ThemeScript } from './components/router-head/theme-script'; +import { Social } from './components/router-head/social'; +import { Vendor } from './components/router-head/vendor'; export const uwu = /*javascript*/ ` ;(function () { @@ -41,6 +49,10 @@ export const uwu = /*javascript*/ ` `; export default component$(() => { + useQwikRouter(); + const head = useDocumentHead(); + const { url } = useLocation(); + const store = useStore({ headerMenuOpen: false, sideMenuOpen: false, @@ -48,12 +60,94 @@ export default component$(() => { useContextProvider(GlobalStore, store); + const title = head.title + ? `${head.title} 📚 Qwik Documentation` + : `Qwik - Framework reimagined for the edge`; + const description = + head.meta.find((m) => m.name === 'description')?.content || + `No hydration, auto lazy-loading, edge-optimized, and fun 🎉!`; + + const OGImage = { + imageURL: '', + ogImgTitle: '', + ogImgSubTitle: '' as string | undefined, + + get URL() { + //turn the title into array with [0] -> Title [1] -> subTitle + const arrayedTitle = title.split(' | '); + const ogImageUrl = new URL('https://opengraphqwik.vercel.app/api/og?level=1'); + + // biggerTitle + this.ogImgTitle = arrayedTitle[0]; + //smallerTitle + this.ogImgSubTitle = arrayedTitle[1] + ? arrayedTitle[1].replace(' 📚 Qwik Documentation', '') + : undefined; + + //decide whether or not to show dynamic OGimage or use docs default social card + if (this.ogImgSubTitle == undefined || this.ogImgTitle == undefined) { + this.imageURL = new URL(`/logos/social-card.jpg`, url).href; + + return this.imageURL; + } else { + ogImageUrl.searchParams.set('title', this.ogImgTitle); + ogImageUrl.searchParams.set('subtitle', this.ogImgSubTitle); + // ogImageUrl.searchParams.set('level', this.routeLevel.toString()); + + this.imageURL = ogImageUrl.toString(); + + return this.imageURL; + } + }, + }; + return ( - + <> + + {title} + + + + + + + + + + + + + {import.meta.env.PROD && ( + <> + + + + )} + + {/* The below are tags that were collected from all the `head` exports in the current route. */} + {head.meta + // Skip description because that was already added at the top + .filter((s) => s.name !== 'description') + .map((m, key) => ( + + ))} + + {head.links.map((l, key) => ( + + ))} + + {head.styles.map((s, key) => ( +