Skip to content

Commit d23e066

Browse files
authored
Merge pull request #7731 from QwikDev/useqwikrouter
feat: useQwikRouter
2 parents 824c58f + 33f63d9 commit d23e066

File tree

21 files changed

+301
-219
lines changed

21 files changed

+301
-219
lines changed

.changeset/every-badgers-bake.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@qwik.dev/router': minor
3+
---
4+
5+
FEAT: useQwikRouter() hook replaces QwikRouterProvider. This gives access to the context immediately and is slightly more efficient.

e2e/adapters-e2e/src/components/router-head/router-head.tsx

Lines changed: 0 additions & 24 deletions
This file was deleted.

e2e/adapters-e2e/src/root.tsx

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,24 @@
11
import { component$ } from '@qwik.dev/core';
2-
import { QwikRouterProvider, RouterOutlet } from '@qwik.dev/router';
3-
import { RouterHead } from './components/router-head/router-head';
2+
import { DocumentHeadTags, RouterOutlet, useLocation, useQwikRouter } from '@qwik.dev/router';
43

54
export default component$(() => {
6-
/**
7-
* The root of a QwikCity site always start with the <QwikCityProvider> component, immediately
8-
* followed by the document's <head> and <body>.
9-
*
10-
* Don't remove the `<head>` and `<body>` elements.
11-
*/
5+
useQwikRouter();
6+
7+
const loc = useLocation();
128

139
return (
14-
<QwikRouterProvider>
10+
<>
1511
<head>
1612
<meta charset="utf-8" />
17-
<RouterHead />
13+
14+
<DocumentHeadTags />
15+
16+
<link rel="canonical" href={loc.url.href} />
17+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
1818
</head>
19-
<body lang="en">
19+
<body>
2020
<RouterOutlet />
2121
</body>
22-
</QwikRouterProvider>
22+
</>
2323
);
2424
});

packages/docs/src/root.tsx

Lines changed: 100 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,19 @@
11
import { component$, useContextProvider, useStore } from '@qwik.dev/core';
22
import { Insights } from '@qwik.dev/core/insights';
3-
import { QwikRouterProvider, RouterOutlet, ServiceWorkerRegister } from '@qwik.dev/router';
3+
import {
4+
RouterOutlet,
5+
ServiceWorkerRegister,
6+
useDocumentHead,
7+
useLocation,
8+
useQwikRouter,
9+
} from '@qwik.dev/router';
410
import RealMetricsOptimization from './components/real-metrics-optimization/real-metrics-optimization';
5-
import { RouterHead } from './components/router-head/router-head';
611
import { BUILDER_PUBLIC_API_KEY } from './constants';
712
import { GlobalStore, type SiteStore } from './context';
813
import './global.css';
14+
import { ThemeScript } from './components/router-head/theme-script';
15+
import { Social } from './components/router-head/social';
16+
import { Vendor } from './components/router-head/vendor';
917

1018
export const uwu = /*javascript*/ `
1119
;(function () {
@@ -41,19 +49,105 @@ export const uwu = /*javascript*/ `
4149
`;
4250

4351
export default component$(() => {
52+
useQwikRouter();
53+
const head = useDocumentHead();
54+
const { url } = useLocation();
55+
4456
const store = useStore<SiteStore>({
4557
headerMenuOpen: false,
4658
sideMenuOpen: false,
4759
});
4860

4961
useContextProvider(GlobalStore, store);
5062

63+
const title = head.title
64+
? `${head.title} 📚 Qwik Documentation`
65+
: `Qwik - Framework reimagined for the edge`;
66+
const description =
67+
head.meta.find((m) => m.name === 'description')?.content ||
68+
`No hydration, auto lazy-loading, edge-optimized, and fun 🎉!`;
69+
70+
const OGImage = {
71+
imageURL: '',
72+
ogImgTitle: '',
73+
ogImgSubTitle: '' as string | undefined,
74+
75+
get URL() {
76+
//turn the title into array with [0] -> Title [1] -> subTitle
77+
const arrayedTitle = title.split(' | ');
78+
const ogImageUrl = new URL('https://opengraphqwik.vercel.app/api/og?level=1');
79+
80+
// biggerTitle
81+
this.ogImgTitle = arrayedTitle[0];
82+
//smallerTitle
83+
this.ogImgSubTitle = arrayedTitle[1]
84+
? arrayedTitle[1].replace(' 📚 Qwik Documentation', '')
85+
: undefined;
86+
87+
//decide whether or not to show dynamic OGimage or use docs default social card
88+
if (this.ogImgSubTitle == undefined || this.ogImgTitle == undefined) {
89+
this.imageURL = new URL(`/logos/social-card.jpg`, url).href;
90+
91+
return this.imageURL;
92+
} else {
93+
ogImageUrl.searchParams.set('title', this.ogImgTitle);
94+
ogImageUrl.searchParams.set('subtitle', this.ogImgSubTitle);
95+
// ogImageUrl.searchParams.set('level', this.routeLevel.toString());
96+
97+
this.imageURL = ogImageUrl.toString();
98+
99+
return this.imageURL;
100+
}
101+
},
102+
};
103+
51104
return (
52-
<QwikRouterProvider>
105+
<>
53106
<head>
54107
<meta charset="utf-8" />
108+
109+
<title>{title}</title>
110+
<meta name="description" content={description} />
111+
<link rel="canonical" href={head.frontmatter?.canonical || url.href} />
112+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
113+
<meta name="apple-mobile-web-app-title" content="Qwik" />
114+
<meta name="application-name" content="Qwik" />
115+
<meta name="apple-mobile-web-app-title" content="Qwik" />
116+
<meta name="theme-color" content="#006ce9" />
117+
<meta name="color-scheme" content="dark light" />
118+
119+
<link rel="apple-touch-icon" sizes="180x180" href="/favicons/apple-touch-icon.png" />
120+
<link rel="icon" href="/favicons/favicon.svg" type="image/svg+xml" />
121+
122+
{import.meta.env.PROD && (
123+
<>
124+
<Social title={title} description={description} href={url.href} ogImage={OGImage.URL} />
125+
<Vendor />
126+
</>
127+
)}
128+
129+
{/* The below are tags that were collected from all the `head` exports in the current route. */}
130+
{head.meta
131+
// Skip description because that was already added at the top
132+
.filter((s) => s.name !== 'description')
133+
.map((m, key) => (
134+
<meta key={key} {...m} />
135+
))}
136+
137+
{head.links.map((l, key) => (
138+
<link key={key} {...l} />
139+
))}
140+
141+
{head.styles.map((s, key) => (
142+
<style key={key} {...s.props} dangerouslySetInnerHTML={s.style} />
143+
))}
144+
145+
{head.scripts.map((s, key) => (
146+
<script key={key} {...s.props} dangerouslySetInnerHTML={s.script} />
147+
))}
148+
149+
<ThemeScript />
55150
<script dangerouslySetInnerHTML={uwu} />
56-
<RouterHead />
57151

58152
<ServiceWorkerRegister />
59153

@@ -66,10 +160,11 @@ export default component$(() => {
66160
'menu-open': store.sideMenuOpen,
67161
}}
68162
>
163+
{/* This renders the current route, including all Layout components. */}
69164
<RouterOutlet />
70165
<RealMetricsOptimization builderApiKey={BUILDER_PUBLIC_API_KEY} />
71166
</body>
72-
</QwikRouterProvider>
167+
</>
73168
);
74169
});
75170

packages/docs/src/routes/api/qwik-router/api.json

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -600,7 +600,7 @@
600600
}
601601
],
602602
"kind": "Variable",
603-
"content": "> Warning: This API is now obsolete.\n> \n> Use `QwikRouterMockProvider` instead. Will be removed in V3\n> \n\n\n```typescript\nQwikCityMockProvider: import(\"@qwik.dev/core\").Component<QwikRouterMockProps>\n```",
603+
"content": "> Warning: This API is now obsolete.\n> \n> Use `useQwikMockRouter()` instead. Will be removed in V3\n> \n\n\n```typescript\nQwikCityMockProvider: import(\"@qwik.dev/core\").Component<QwikRouterMockProps>\n```",
604604
"editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik-router/src/runtime/src/qwik-router-component.tsx",
605605
"mdFile": "router.qwikcitymockprovider.md"
606606
},
@@ -628,7 +628,7 @@
628628
}
629629
],
630630
"kind": "TypeAlias",
631-
"content": "> Warning: This API is now obsolete.\n> \n> Use `QwikRouterProps` instead. will be removed in V3\n> \n\n\n```typescript\nexport type QwikCityProps = QwikRouterProps;\n```\n**References:** [QwikRouterProps](#qwikrouterprops)",
631+
"content": "> Warning: This API is now obsolete.\n> \n> Use `QwikRouterProps` instead. Will be removed in v3.\n> \n\n\n```typescript\nexport type QwikCityProps = QwikRouterProps;\n```\n**References:** [QwikRouterProps](#qwikrouterprops)",
632632
"editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik-router/src/runtime/src/qwik-router-component.tsx",
633633
"mdFile": "router.qwikcityprops.md"
634634
},
@@ -642,7 +642,7 @@
642642
}
643643
],
644644
"kind": "Variable",
645-
"content": "> Warning: This API is now obsolete.\n> \n> Use `QwikRouterProvider` instead. will be removed in V3\n> \n\n\n```typescript\nQwikCityProvider: import(\"@qwik.dev/core\").Component<QwikRouterProps>\n```",
645+
"content": "> Warning: This API is now obsolete.\n> \n> Use `useQwikRouter()` instead. Will be removed in v3.\n> \n\n\n```typescript\nQwikCityProvider: import(\"@qwik.dev/core\").Component<QwikRouterProps>\n```",
646646
"editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik-router/src/runtime/src/qwik-router-component.tsx",
647647
"mdFile": "router.qwikcityprovider.md"
648648
},
@@ -726,7 +726,7 @@
726726
}
727727
],
728728
"kind": "Variable",
729-
"content": "```typescript\nQwikRouterProvider: import(\"@qwik.dev/core\").Component<QwikRouterProps>\n```",
729+
"content": "This is a wrapper around the `useQwikRouter()` hook. We recommend using the hook instead of this component.\n\n\n```typescript\nQwikRouterProvider: import(\"@qwik.dev/core\").Component<QwikRouterProps>\n```",
730730
"editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik-router/src/runtime/src/qwik-router-component.tsx",
731731
"mdFile": "router.qwikrouterprovider.md"
732732
},
@@ -1066,6 +1066,20 @@
10661066
"editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik-router/src/runtime/src/use-functions.ts",
10671067
"mdFile": "router.usepreventnavigate_.md"
10681068
},
1069+
{
1070+
"name": "useQwikRouter",
1071+
"id": "useqwikrouter",
1072+
"hierarchy": [
1073+
{
1074+
"name": "useQwikRouter",
1075+
"id": "useqwikrouter"
1076+
}
1077+
],
1078+
"kind": "Function",
1079+
"content": "This hook initializes Qwik Router, providing the necessary context for it to work.\n\nThis hook should be used once, at the root of your application.\n\n\n```typescript\nuseQwikRouter: (props?: QwikRouterProps) => void\n```\n\n\n<table><thead><tr><th>\n\nParameter\n\n\n</th><th>\n\nType\n\n\n</th><th>\n\nDescription\n\n\n</th></tr></thead>\n<tbody><tr><td>\n\nprops\n\n\n</td><td>\n\n[QwikRouterProps](#qwikrouterprops)\n\n\n</td><td>\n\n_(Optional)_\n\n\n</td></tr>\n</tbody></table>\n**Returns:**\n\nvoid",
1080+
"editUrl": "https://github.com/QwikDev/qwik/tree/main/packages/qwik-router/src/runtime/src/qwik-router-component.tsx",
1081+
"mdFile": "router.useqwikrouter.md"
1082+
},
10691083
{
10701084
"name": "valibot$",
10711085
"id": "valibot_",

packages/docs/src/routes/api/qwik-router/index.mdx

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1400,7 +1400,7 @@ export type QwikCityMockProps = QwikRouterMockProps;
14001400
14011401
> Warning: This API is now obsolete.
14021402
>
1403-
> Use `QwikRouterMockProvider` instead. Will be removed in V3
1403+
> Use `useQwikMockRouter()` instead. Will be removed in V3
14041404
14051405
```typescript
14061406
QwikCityMockProvider: import("@qwik.dev/core").Component<QwikRouterMockProps>;
@@ -1426,7 +1426,7 @@ export type QwikCityPlan = QwikRouterConfig;
14261426
14271427
> Warning: This API is now obsolete.
14281428
>
1429-
> Use `QwikRouterProps` instead. will be removed in V3
1429+
> Use `QwikRouterProps` instead. Will be removed in v3.
14301430
14311431
```typescript
14321432
export type QwikCityProps = QwikRouterProps;
@@ -1440,7 +1440,7 @@ export type QwikCityProps = QwikRouterProps;
14401440
14411441
> Warning: This API is now obsolete.
14421442
>
1443-
> Use `QwikRouterProvider` instead. will be removed in V3
1443+
> Use `useQwikRouter()` instead. Will be removed in v3.
14441444
14451445
```typescript
14461446
QwikCityProvider: import("@qwik.dev/core").Component<QwikRouterProps>;
@@ -1793,6 +1793,8 @@ Default: `true`
17931793
17941794
## QwikRouterProvider
17951795
1796+
This is a wrapper around the `useQwikRouter()` hook. We recommend using the hook instead of this component.
1797+
17961798
```typescript
17971799
QwikRouterProvider: import("@qwik.dev/core").Component<QwikRouterProps>;
17981800
```
@@ -2375,6 +2377,49 @@ void
23752377

23762378
[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik-router/src/runtime/src/use-functions.ts)
23772379

2380+
## useQwikRouter
2381+
2382+
This hook initializes Qwik Router, providing the necessary context for it to work.
2383+
2384+
This hook should be used once, at the root of your application.
2385+
2386+
```typescript
2387+
useQwikRouter: (props?: QwikRouterProps) => void
2388+
```
2389+
2390+
<table><thead><tr><th>
2391+
2392+
Parameter
2393+
2394+
</th><th>
2395+
2396+
Type
2397+
2398+
</th><th>
2399+
2400+
Description
2401+
2402+
</th></tr></thead>
2403+
<tbody><tr><td>
2404+
2405+
props
2406+
2407+
</td><td>
2408+
2409+
[QwikRouterProps](#qwikrouterprops)
2410+
2411+
</td><td>
2412+
2413+
_(Optional)_
2414+
2415+
</td></tr>
2416+
</tbody></table>
2417+
**Returns:**
2418+
2419+
void
2420+
2421+
[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik-router/src/runtime/src/qwik-router-component.tsx)
2422+
23782423
## valibot$
23792424

23802425
> This API is provided as a beta preview for developers and may change based on feedback that we receive. Do not use this API in a production environment.

0 commit comments

Comments
 (0)