Skip to content

Commit

Permalink
✨ feat: Add ld
Browse files Browse the repository at this point in the history
  • Loading branch information
canisminor1990 committed Nov 24, 2024
1 parent db1d9cf commit 533e9c4
Show file tree
Hide file tree
Showing 7 changed files with 126 additions and 9 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
"rc-footer": "^0.6.8",
"react-layout-kit": "^1.9.0",
"swr": "^2.2.5",
"url-join": "^5.0.0",
"use-merge-value": "^1.2.0",
"zustand": "^4.5.5",
"zustand-utils": "^1.3.2"
Expand Down
6 changes: 4 additions & 2 deletions src/components/Analytics/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { Helmet } from 'dumi';

import { siteSelectors, useSiteStore } from '@/store';

import ClarityAnalytics from './Clarity';
Expand All @@ -7,7 +9,7 @@ import Plausible from './Plausible';
const Analytics = () => {
const analytics = useSiteStore(siteSelectors.analytics);
return (
<>
<Helmet>
{analytics?.googleAnalytics && (
<GoogleAnalytics measurementId={analytics.googleAnalytics.measurementId} />
)}
Expand All @@ -18,7 +20,7 @@ const Analytics = () => {
scriptBaseUrl={analytics.plausible.scriptBaseUrl}
/>
)}
</>
</Helmet>
);
};

Expand Down
12 changes: 12 additions & 0 deletions src/components/StructuredData/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { FC } from 'react';

const StructuredData: FC<{ ld: any }> = ({ ld }) => {
return (
<script
dangerouslySetInnerHTML={{ __html: JSON.stringify(ld) }}
id="structured-data"
type="application/ld+json"
/>
);
};
export default StructuredData;
6 changes: 3 additions & 3 deletions src/layouts/DocLayout/Head/Favicons.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { Helmet } from 'dumi';
import isEqual from 'fast-deep-equal';
import { memo } from 'react';
import { FC } from 'react';

import { siteSelectors, useSiteStore } from '@/store';

const Favicons = memo(() => {
const Favicons: FC = () => {
const [title, logo] = useSiteStore((s) => [siteSelectors.siteTitle(s), siteSelectors.logo(s)]);
const metadata = useSiteStore(siteSelectors.metadata, isEqual);
return (
Expand All @@ -19,6 +19,6 @@ const Favicons = memo(() => {
<meta content="#000" media="(prefers-color-scheme: dark)" name="theme-color" />
</Helmet>
);
});
};

export default Favicons;
10 changes: 6 additions & 4 deletions src/layouts/DocLayout/Head/Og.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { Helmet } from 'dumi';
import isEqual from 'fast-deep-equal';
import { memo } from 'react';
import { FC } from 'react';
import urlJoin from 'url-join';

import { siteSelectors, useSiteStore } from '@/store';

const Og = memo(() => {
const Og: FC = () => {
const [title, desc, logo, hostname] = useSiteStore((s) => [
siteSelectors.siteTitle(s),
siteSelectors.siteDesc(s),
Expand All @@ -16,9 +17,10 @@ const Og = memo(() => {
<Helmet>
<title>{metadata?.title || title}</title>
<meta content={metadata?.description || desc} name="description" />
<link href={hostname || location.origin} rel="canonical" />
<meta content={metadata?.openGraph?.title || title} property="og:title" />
<meta content={metadata?.openGraph?.description || desc} property="og:description" />
<meta content={hostname || location.origin} property="og:url" />
<meta content={urlJoin(hostname || location.origin, location.pathname)} property="og:url" />
<meta content={metadata?.openGraph?.siteName} property="og:site_name" />
<meta content="en" property="og:locale" />
<meta content={metadata?.openGraph?.title || title} property="og:image:alt" />
Expand All @@ -41,6 +43,6 @@ const Og = memo(() => {
/>
</Helmet>
);
});
};

export default Og;
98 changes: 98 additions & 0 deletions src/layouts/DocLayout/Head/StructuredData.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import { Helmet } from 'dumi';
import isEqual from 'fast-deep-equal';
import { FC } from 'react';
import urlJoin from 'url-join';

import { siteSelectors, useSiteStore } from '@/store';

const date = new Date().toISOString();

const StructuredData: FC = () => {
const [title, desc, logo, hostname] = useSiteStore((s) => [
siteSelectors.siteTitle(s),
siteSelectors.siteDesc(s),
siteSelectors.logo(s),
siteSelectors.hostname(s),
]);
const metadata = useSiteStore(siteSelectors.metadata, isEqual);
const host = hostname || location.origin;

const ld = {
'@context': 'https://schema.org',
'@graph': [
{
'@id': urlJoin(host, '#website'),
'@type': 'WebSite',
'description': desc,
'inLanguage': 'en-US',
'name': 'LobeHub',
'publisher': { '@id': urlJoin(host, '#organization') },
'url': host,
},
{
'@id': host,
'@type': 'WebPage',
'about': { '@id': urlJoin(host, '#organization') },
'dateModified': date,
'datePublished': date,
'description': desc,
'image': { '@id': urlJoin(host, '#primaryimage') },
'inLanguage': 'en-US',
'isPartOf': { '@id': urlJoin(host, '#website') },
'name': title,
'primaryImageOfPage': { '@id': urlJoin(host, '#primaryimage') },
'thumbnailUrl': metadata?.twitter?.image || metadata?.openGraph?.image,
},
{
'@id': urlJoin(host, '#primaryimage'),
'@type': 'ImageObject',
'contentUrl': metadata?.twitter?.image || metadata?.openGraph?.image || logo,
'inLanguage': 'en-US',
'url': metadata?.twitter?.image || metadata?.openGraph?.image || logo,
},
{
'@id': urlJoin(host, '#organization'),
'@type': 'Organization',
'alternateName': 'LobeHub',
'contactPoint': {
'@type': 'ContactPoint',
'contactType': 'customer support',
'email': '[email protected]',
},
'description':
'We are a group of e/acc design-engineers, hoping to provide modern design components and tools for AIGC, and creating a technology-driven forum, fostering knowledge interaction and the exchange of ideas that may culminate in mutual inspiration and collaborative innovation.',
'email': '[email protected]',
'founders': [
{ '@type': 'Person', 'name': 'Arvin Xu', 'url': 'https://github.com/arvinxx' },
{ '@type': 'Person', 'name': 'CanisMinor', 'url': 'https://github.com/arvinxx' },
],
'image': 'https://lobehub.com/icon-512x512.png',
'logo': {
'@type': 'ImageObject',
'height': 512,
'url': 'https://lobehub.com/icon-512x512.png',
'width': 512,
},
'name': 'LobeHub',
'sameAs': [
'https://x.com/lobehub',
'https://github.com/lobehub',
'https://medium.com/@lobehub',
'https://www.youtube.com/@lobehub',
],
'url': 'https://lobehub.com',
},
],
};

return (
<Helmet>
<script
dangerouslySetInnerHTML={{ __html: JSON.stringify(ld) }}
id="structured-data"
type="application/ld+json"
/>
</Helmet>
);
};
export default StructuredData;
2 changes: 2 additions & 0 deletions src/layouts/DocLayout/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,15 @@ import { Provider, createStore } from '@/store';
import DocumentLayout from './DocumentLayout';
import Favicons from './Head/Favicons';
import Og from './Head/Og';
import StructuredData from './Head/StructuredData';
import ThemeProvider from './ThemeProvider';

const App = memo(({ initState }: any) => {
return (
<Provider createStore={() => createStore(initState)}>
<Favicons />
<Og />
<StructuredData />
<Analytics />
<StoreUpdater />
<ThemeProvider>
Expand Down

0 comments on commit 533e9c4

Please sign in to comment.