mirror of
https://github.com/graphql-hive/console
synced 2026-05-23 17:18:23 +00:00
Use FAQPage (#6017)
This commit is contained in:
parent
c86368204f
commit
c337719a48
3 changed files with 100 additions and 25 deletions
|
|
@ -2,7 +2,7 @@ import { Children, ComponentPropsWithoutRef } from 'react';
|
|||
import * as Accordion from '@radix-ui/react-accordion';
|
||||
import { ChevronDownIcon } from '@radix-ui/react-icons';
|
||||
import { Anchor, Heading } from '@theguild/components';
|
||||
import { cn } from '../../lib';
|
||||
import { cn, usePageFAQSchema } from '../../lib';
|
||||
import FederationQuestions from './federation-questions.mdx';
|
||||
import HomeQuestions from './home-questions.mdx';
|
||||
|
||||
|
|
@ -53,21 +53,29 @@ const li = (props: ComponentPropsWithoutRef<'li'>) => {
|
|||
asChild
|
||||
value={question}
|
||||
className="rdx-state-open:pb-4 relative pb-0 focus-within:z-10"
|
||||
itemScope
|
||||
itemProp="mainEntity"
|
||||
itemType="https://schema.org/Question"
|
||||
>
|
||||
<li>
|
||||
<Accordion.Header>
|
||||
<Accordion.Trigger className="hive-focus hover:bg-beige-100/80 -mx-2 my-1 flex w-[calc(100%+1rem)] items-center justify-between rounded-xl bg-white px-2 py-3 text-left font-medium transition-colors duration-[.8s] md:my-2 md:py-4">
|
||||
{question}
|
||||
<span itemProp="name">{question}</span>
|
||||
<ChevronDownIcon className="size-5 [[data-state='open']_&]:[transform:rotateX(180deg)]" />
|
||||
</Accordion.Trigger>
|
||||
</Accordion.Header>
|
||||
<Accordion.Content
|
||||
forceMount
|
||||
className="space-y-2 overflow-hidden bg-white text-green-800 data-[state=closed]:hidden"
|
||||
className="overflow-hidden bg-white text-green-800 data-[state=closed]:hidden"
|
||||
itemScope
|
||||
itemProp="acceptedAnswer"
|
||||
itemType="https://schema.org/Answer"
|
||||
>
|
||||
{answers.map((answer, i) => (
|
||||
<p key={i}>{answer}</p>
|
||||
))}
|
||||
<div itemProp="text" className="space-y-2">
|
||||
{answers.map((answer, i) => (
|
||||
<p key={i}>{answer}</p>
|
||||
))}
|
||||
</div>
|
||||
</Accordion.Content>
|
||||
</li>
|
||||
</Accordion.Item>
|
||||
|
|
@ -82,27 +90,35 @@ const components = {
|
|||
};
|
||||
|
||||
export function FrequentlyAskedQuestions({ className }: { className?: string }) {
|
||||
usePageFAQSchema();
|
||||
|
||||
return (
|
||||
<section
|
||||
className={cn(
|
||||
className,
|
||||
'text-green-1000 flex flex-col gap-x-6 gap-y-2 px-4 py-6 md:flex-row md:px-10 lg:gap-x-24 lg:px-[120px] lg:py-24',
|
||||
)}
|
||||
>
|
||||
<HomeQuestions components={components} />
|
||||
</section>
|
||||
<>
|
||||
<section
|
||||
className={cn(
|
||||
className,
|
||||
'text-green-1000 flex flex-col gap-x-6 gap-y-2 px-4 py-6 md:flex-row md:px-10 lg:gap-x-24 lg:px-[120px] lg:py-24',
|
||||
)}
|
||||
>
|
||||
<HomeQuestions components={components} />
|
||||
</section>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export function FrequentlyAskedFederationQuestions({ className }: { className?: string }) {
|
||||
usePageFAQSchema();
|
||||
|
||||
return (
|
||||
<section
|
||||
className={cn(
|
||||
className,
|
||||
'text-green-1000 flex flex-col gap-x-6 gap-y-2 px-4 py-6 md:flex-row md:px-10 lg:gap-x-24 lg:px-[120px] lg:py-24',
|
||||
)}
|
||||
>
|
||||
<FederationQuestions components={components} />
|
||||
</section>
|
||||
<>
|
||||
<section
|
||||
className={cn(
|
||||
className,
|
||||
'text-green-1000 flex flex-col gap-x-6 gap-y-2 px-4 py-6 md:flex-row md:px-10 lg:gap-x-24 lg:px-[120px] lg:py-24',
|
||||
)}
|
||||
>
|
||||
<FederationQuestions components={components} />
|
||||
</section>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,3 +19,36 @@ export function useTheme() {
|
|||
};
|
||||
}, []);
|
||||
}
|
||||
|
||||
const pagesWithFAQ = ['/', '/federation', '/pricing'];
|
||||
|
||||
export function isPageWithFaq(path: string) {
|
||||
return pagesWithFAQ.includes(path);
|
||||
}
|
||||
|
||||
export function usePageFAQSchema() {
|
||||
useEffect(() => {
|
||||
if (typeof window === 'undefined') {
|
||||
return;
|
||||
}
|
||||
|
||||
const html = document.querySelector('html');
|
||||
|
||||
if (!html) {
|
||||
// This should never happen
|
||||
return;
|
||||
}
|
||||
|
||||
const path = window.location.pathname.replace('/graphql/hive', '/');
|
||||
|
||||
if (isPageWithFaq(path) && !html.hasAttribute('itemscope')) {
|
||||
html.setAttribute('itemscope', '');
|
||||
html.setAttribute('itemtype', 'https://schema.org/FAQPage');
|
||||
|
||||
return () => {
|
||||
html.removeAttribute('itemscope');
|
||||
html.removeAttribute('itemtype');
|
||||
};
|
||||
}
|
||||
}, []);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,36 @@
|
|||
import { Head, Html, Main, NextScript } from 'next/document';
|
||||
import { DocumentProps, Head, Html, Main, NextScript } from 'next/document';
|
||||
import { isPageWithFaq } from '../lib';
|
||||
|
||||
export default function Document(props: DocumentProps) {
|
||||
// Can't do <Head><html .../></Head>...
|
||||
// We need to add the structured data attributes
|
||||
// to the html tag this way.
|
||||
// We can remove this when Nextra is fixed
|
||||
// Currently, the pages with FAQ are:
|
||||
// /
|
||||
// /federation
|
||||
// /pricing
|
||||
//
|
||||
// This workaround works only partially.
|
||||
// Yes, the structured data is added to the html tag on initial page visit,
|
||||
// but when navigating to another page, the structured data is not updated,
|
||||
// and the html tag is showing the structured data from the previous page.
|
||||
// That's why we need to listen to the route change and update the structured data.
|
||||
// See: usePageFAQSchema in lib.ts
|
||||
const isFAQPage = isPageWithFaq(props.__NEXT_DATA__.page);
|
||||
|
||||
export default function Document() {
|
||||
return (
|
||||
// We can drop it when Nextra is fixed
|
||||
// The html[lang] is not being added by Nextra
|
||||
<Html lang="en">
|
||||
<Html
|
||||
lang="en"
|
||||
{...(isFAQPage
|
||||
? {
|
||||
itemScope: true,
|
||||
itemType: 'https://schema.org/FAQPage',
|
||||
}
|
||||
: {})}
|
||||
>
|
||||
<Head />
|
||||
<body>
|
||||
<Main />
|
||||
|
|
|
|||
Loading…
Reference in a new issue