Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[blog] Improve SEO metadata #33954

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/pages/experiments/docs/callouts.js
@@ -1,7 +1,7 @@
import * as React from 'react';
import TopLayoutBlog from 'docs/src/modules/components/TopLayoutBlog';
import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs';
import { docs } from './callouts.md?@mui/markdown';

export default function Page() {
return <TopLayoutBlog docs={docs} />;
return <MarkdownDocs docs={docs} />;
}
@@ -1,15 +1,24 @@
import * as React from 'react';
import NextHead from 'next/head';
import { useRouter } from 'next/router';
import PropTypes from 'prop-types';
import { LANGUAGES_SSR } from 'docs/src/modules/constants';
import { useUserLanguage, useTranslate } from 'docs/src/modules/utils/i18n';
import { pathnameToLanguage } from 'docs/src/modules/utils/helpers';

// #major-version-switch
const HOST = 'https://mui.com';

export default function Head(props) {
interface HeadProps {
card?: string;
children?: React.ReactNode;
description: string;
disableAlternateLocale?: boolean;
largeCard?: boolean;
title: string;
type?: string;
}

export default function Head(props: HeadProps) {
const t = useTranslate();
const {
card = '/static/social-previews/default-preview.jpg',
Expand All @@ -18,11 +27,12 @@ export default function Head(props) {
disableAlternateLocale = false,
largeCard = true,
title = t('headTitle'),
type = 'website',
} = props;
const userLanguage = useUserLanguage();
const router = useRouter();
const preview = card.startsWith('http') ? card : `${HOST}${card}`;
const { canonicalAs } = pathnameToLanguage(router.asPath);
const preview = card.startsWith('http') ? card : `${HOST}${card}`;

return (
<NextHead>
Expand All @@ -37,7 +47,7 @@ export default function Head(props) {
<meta name="twitter:description" content={description} />
<meta name="twitter:image" content={preview} />
{/* Facebook */}
<meta property="og:type" content="website" />
<meta property="og:type" content={type} />
<meta property="og:title" content={title} />
{/* #major-version-switch */}
<meta property="og:url" content={`${HOST}${router.asPath}`} />
Expand All @@ -64,12 +74,3 @@ export default function Head(props) {
</NextHead>
);
}

Head.propTypes = {
card: PropTypes.string,
children: PropTypes.node,
description: PropTypes.string,
disableAlternateLocale: PropTypes.bool,
largeCard: PropTypes.bool,
title: PropTypes.string,
};
75 changes: 64 additions & 11 deletions docs/src/modules/components/TopLayoutBlog.js
@@ -1,20 +1,21 @@
import * as React from 'react';
import PropTypes from 'prop-types';
import { styled, alpha } from '@mui/material/styles';
import { useRouter } from 'next/router';
import { exactProp } from '@mui/utils';
import ChevronLeftRoundedIcon from '@mui/icons-material/ChevronLeftRounded';
import Divider from '@mui/material/Divider';
import Typography from '@mui/material/Typography';
import Avatar from '@mui/material/Avatar';
import Head from 'docs/src/modules/components/Head';
import BrandingProvider from 'docs/src/BrandingProvider';
import AppHeader from 'docs/src/layouts/AppHeader';
import AppContainer from 'docs/src/modules/components/AppContainer';
import AppFooter from 'docs/src/layouts/AppFooter';
import HeroEnd from 'docs/src/components/home/HeroEnd';
import { useRouter } from 'next/router';
import { exactProp } from '@mui/utils';
import Divider from '@mui/material/Divider';
import Typography from '@mui/material/Typography';
import Avatar from '@mui/material/Avatar';
import MarkdownElement from 'docs/src/modules/components/MarkdownElement';
import { pathnameToLanguage } from 'docs/src/modules/utils/helpers';
import ROUTES from 'docs/src/route';
import ChevronLeftRoundedIcon from '@mui/icons-material/ChevronLeftRounded';
import Link from 'docs/src/modules/components/Link';

export const authors = {
Expand Down Expand Up @@ -213,6 +214,11 @@ function TopLayoutBlog(props) {
const { description, rendered, title, headers } = docs.en;
const finalTitle = title || headers.title;
const router = useRouter();
const { canonicalAs } = pathnameToLanguage(router.asPath);
const card =
headers.card === 'true'
? `https://mui.com/static${router.pathname}/card.png`
: 'https://mui.com/static/logo.png';

return (
<BrandingProvider>
Expand All @@ -222,11 +228,8 @@ function TopLayoutBlog(props) {
description={description}
largeCard={headers.card === 'true'}
disableAlternateLocale
card={
headers.card === 'true'
? `https://mui.com/static${router.pathname}/card.png`
: 'https://mui.com/static/logo.png'
}
card={card}
type="article"
/>
<Root className={className}>
<AppContainer component="main" className={classes.container}>
Expand Down Expand Up @@ -293,6 +296,56 @@ function TopLayoutBlog(props) {
<Divider />
<AppFooter />
</Root>
<script
type="application/ld+json"
// eslint-disable-next-line react/no-danger
dangerouslySetInnerHTML={{
__html: `
{
"@context": "https://schema.org",
"@type": "Article",
"publisher": {
"@type": "Organization",
"name": "MUI blog",
"url": "https://mui.com/blog/",
"logo": {
"@type": "ImageObject",
"url": "https://mui.com/static/icons/512x512.png"
}
},
"author": {
"@type": "Person",
"name": "${authors[headers.authors[0]].name}",
"image": {
"@type": "ImageObject",
"url": "${authors[headers.authors[0]].avatar}?s=${250}",
"width": 250,
"height": 250
},
"sameAs": [
"https://github.com/${authors[headers.authors[0]].github}"
]
},
"headline": "${finalTitle}",
"url": "https://mui.com${canonicalAs}",
"datePublished": "${headers.date}",
"dateModified": "${headers.date}",
"image": {
"@type": "ImageObject",
"url": "${card}",
"width": 1280,
"height": 640
},
"keywords": "${headers.tags.join(', ')}",
"description": "${description}",
"mainEntityOfPage": {
"@type": "WebPage",
"@id": "https://mui.com/blog/"
}
}
`,
}}
/>
</BrandingProvider>
);
}
Expand Down