mirror of
https://github.com/kingomarnajjar/flex-template-web.git
synced 2026-07-28 12:43:11 +10:00
Merge pull request #510 from sharetribe/add-organization-to-schema
Add organization to schema
This commit is contained in:
commit
cc8c685c32
10 changed files with 130 additions and 83 deletions
|
|
@ -21,6 +21,15 @@ const preventDefault = e => {
|
|||
e.preventDefault();
|
||||
};
|
||||
|
||||
const twitterPageURL = siteTwitterHandle => {
|
||||
if (siteTwitterHandle && siteTwitterHandle.charAt(0) === '@') {
|
||||
return `https://twitter.com/${siteTwitterHandle.substring(1)}`;
|
||||
} else if (siteTwitterHandle) {
|
||||
return `https://twitter.com/${siteTwitterHandle}`;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
class PageComponent extends Component {
|
||||
componentDidMount() {
|
||||
this.historyUnlisten = this.props.history.listen(() => scrollToTop());
|
||||
|
|
@ -83,6 +92,7 @@ class PageComponent extends Component {
|
|||
const { pathname, search = '' } = history.location;
|
||||
const pathWithSearch = `${pathname}${search}`;
|
||||
|
||||
const canonicalRootURL = config.canonicalRootURL;
|
||||
const siteTitle = config.siteTitle;
|
||||
const schemaTitle = intl.formatMessage({ id: 'Page.schemaTitle' }, { siteTitle });
|
||||
const schemaDescription = intl.formatMessage({ id: 'Page.schemaDescription' });
|
||||
|
|
@ -91,7 +101,7 @@ class PageComponent extends Component {
|
|||
const facebookImgs = facebookImages || [
|
||||
{
|
||||
name: 'facebook',
|
||||
url: `${config.canonicalRootURL}${facebookImage}`,
|
||||
url: `${canonicalRootURL}${facebookImage}`,
|
||||
width: 1200,
|
||||
height: 630,
|
||||
},
|
||||
|
|
@ -99,7 +109,7 @@ class PageComponent extends Component {
|
|||
const twitterImgs = twitterImages || [
|
||||
{
|
||||
name: 'twitter',
|
||||
url: `${config.canonicalRootURL}${twitterImage}`,
|
||||
url: `${canonicalRootURL}${twitterImage}`,
|
||||
width: 600,
|
||||
height: 314,
|
||||
},
|
||||
|
|
@ -123,17 +133,42 @@ class PageComponent extends Component {
|
|||
// eslint-disable-next-line react/no-array-index-key
|
||||
const metaTags = metaToHead.map((metaProps, i) => <meta key={i} {...metaProps} />);
|
||||
|
||||
const facebookPage = config.siteFacebookPage;
|
||||
const twitterPage = twitterPageURL(config.siteTwitterHandle);
|
||||
const instagramPage = config.siteInstagramPage;
|
||||
const sameOrganizationAs = [facebookPage, twitterPage, instagramPage].filter(v => v != null);
|
||||
|
||||
// Schema for search engines (helps them to understand what this page is about)
|
||||
// http://schema.org
|
||||
// We are using JSON-LD format
|
||||
const schemaJSONString =
|
||||
schema ||
|
||||
JSON.stringify({
|
||||
|
||||
// Schema attribute can be either single schema object or an array of objects
|
||||
// This makes it possible to include several different items from the same page.
|
||||
// E.g. Product, Place, Video
|
||||
const schemaFromProps = Array.isArray(schema) ? schema : [schema];
|
||||
const schemaArrayJSONString = JSON.stringify([
|
||||
...schemaFromProps,
|
||||
{
|
||||
'@context': 'http://schema.org',
|
||||
'@type': 'WebPage',
|
||||
'@type': 'Organization',
|
||||
'@id': `${canonicalRootURL}#organization`,
|
||||
url: canonicalRootURL,
|
||||
name: siteTitle,
|
||||
sameAs: sameOrganizationAs,
|
||||
logo: `${canonicalRootURL}/static/webapp-icon-192x192.png`,
|
||||
address: config.address,
|
||||
},
|
||||
{
|
||||
'@context': 'http://schema.org',
|
||||
'@type': 'WebSite',
|
||||
url: canonicalRootURL,
|
||||
description: schemaDescription,
|
||||
name: schemaTitle,
|
||||
});
|
||||
publisher: {
|
||||
'@id': `${canonicalRootURL}#organization`,
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
return (
|
||||
<div className={classes}>
|
||||
|
|
@ -147,7 +182,7 @@ class PageComponent extends Component {
|
|||
<meta httpEquiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<meta httpEquiv="Content-Language" content={intl.locale} />
|
||||
{metaTags}
|
||||
<script type="application/ld+json">{schemaJSONString}</script>
|
||||
<script type="application/ld+json">{schemaArrayJSONString}</script>
|
||||
</Helmet>
|
||||
{authInfoError ? (
|
||||
<div style={{ color: 'red' }}>
|
||||
|
|
@ -165,7 +200,7 @@ class PageComponent extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
const { any, arrayOf, bool, func, number, shape, string } = PropTypes;
|
||||
const { any, array, arrayOf, bool, func, number, object, oneOfType, shape, string } = PropTypes;
|
||||
|
||||
PageComponent.defaultProps = {
|
||||
className: null,
|
||||
|
|
@ -214,7 +249,7 @@ PageComponent.propTypes = {
|
|||
})
|
||||
),
|
||||
published: string, // article:published_time
|
||||
schema: string, // http://schema.org
|
||||
schema: oneOfType([object, array]), // http://schema.org
|
||||
tags: string, // article:tag
|
||||
title: string.isRequired, // page title
|
||||
twitterHandle: string, // twitter handle
|
||||
|
|
|
|||
|
|
@ -187,15 +187,27 @@ const stripeSupportedCountries = [
|
|||
},
|
||||
];
|
||||
|
||||
// Address information is used in SEO schema for Organization (http://schema.org/PostalAddress)
|
||||
const addressCountry = 'FI';
|
||||
const addressRegion = 'Helsinki';
|
||||
const postalCode = '00100';
|
||||
const streetAddress = 'Bulevardi 14';
|
||||
|
||||
// Canonical root url is needed in social media sharing and SEO optimization purposes.
|
||||
const canonicalRootURL = process.env.REACT_APP_CANONICAL_ROOT_URL || 'http://localhost:3000';
|
||||
|
||||
// Site title is needed in meta tags (bots and social media sharing reads those)
|
||||
const siteTitle = 'Saunatime';
|
||||
|
||||
// Twitter handle is needed in meta tags (twitter:site)
|
||||
// Twitter handle is needed in meta tags (twitter:site). Start it with '@' character
|
||||
const siteTwitterHandle = '@sharetribe';
|
||||
|
||||
// Instagram page is used in SEO schema (http://schema.org/Organization)
|
||||
const siteInstagramPage = null;
|
||||
|
||||
// Facebook page is used in SEO schema (http://schema.org/Organization)
|
||||
const siteFacebookPage = null;
|
||||
|
||||
// Facebook counts shares with app or page associated by this id
|
||||
// Currently it is unset, but you can read more about fb:app_id from
|
||||
// https://developers.facebook.com/docs/sharing/webmasters#basic
|
||||
|
|
@ -212,7 +224,15 @@ const config = {
|
|||
currencyConfig,
|
||||
stripe: { publishableKey: stripePublishableKey, supportedCountries: stripeSupportedCountries },
|
||||
canonicalRootURL,
|
||||
address: {
|
||||
addressCountry,
|
||||
addressRegion,
|
||||
postalCode,
|
||||
streetAddress,
|
||||
},
|
||||
siteTitle,
|
||||
siteFacebookPage,
|
||||
siteInstagramPage,
|
||||
siteTwitterHandle,
|
||||
facebookAppId,
|
||||
sentryDsn,
|
||||
|
|
|
|||
|
|
@ -210,13 +210,11 @@ export const AuthenticationPageComponent = props => {
|
|||
logoutError={logoutError}
|
||||
title={schemaTitle}
|
||||
scrollingDisabled={scrollingDisabled}
|
||||
schema={`
|
||||
{
|
||||
"@context": "http://schema.org",
|
||||
"@type": "WebPage",
|
||||
"name": "${schemaTitle}",
|
||||
}
|
||||
`}
|
||||
schema={{
|
||||
'@context': 'http://schema.org',
|
||||
'@type': 'WebPage',
|
||||
name: schemaTitle,
|
||||
}}
|
||||
>
|
||||
<TopbarContainer className={topbarClasses} />
|
||||
<div className={css.root}>
|
||||
|
|
|
|||
|
|
@ -4,13 +4,13 @@ exports[`AuthenticationPageComponent matches snapshot 1`] = `
|
|||
<Page
|
||||
authInfoError={null}
|
||||
logoutError={null}
|
||||
schema="
|
||||
{
|
||||
\\"@context\\": \\"http://schema.org\\",
|
||||
\\"@type\\": \\"WebPage\\",
|
||||
\\"name\\": \\"AuthenticationPage.schemaTitleLogin\\",
|
||||
}
|
||||
"
|
||||
schema={
|
||||
Object {
|
||||
"@context": "http://schema.org",
|
||||
"@type": "WebPage",
|
||||
"name": "AuthenticationPage.schemaTitleLogin",
|
||||
}
|
||||
}
|
||||
scrollingDisabled={false}
|
||||
title="AuthenticationPage.schemaTitleLogin"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -36,17 +36,13 @@ export const LandingPageComponent = props => {
|
|||
title={schemaTitle}
|
||||
facebookImages={[{ url: facebookImage, width: 1200, height: 630 }]}
|
||||
twitterImages={[{ url: twitterImage, width: 600, height: 314 }]}
|
||||
schema={`
|
||||
{
|
||||
"@context": "http://schema.org",
|
||||
"@type": "WebPage",
|
||||
"description": "${schemaDescription}",
|
||||
"name": "${schemaTitle}",
|
||||
"image": [
|
||||
"${schemaImage}"
|
||||
]
|
||||
}
|
||||
`}
|
||||
schema={{
|
||||
'@context': 'http://schema.org',
|
||||
'@type': 'WebPage',
|
||||
description: schemaDescription,
|
||||
name: schemaTitle,
|
||||
image: [schemaImage],
|
||||
}}
|
||||
>
|
||||
<TopbarContainer />
|
||||
<div className={css.heroContainer}>
|
||||
|
|
|
|||
|
|
@ -15,17 +15,17 @@ exports[`LandingPage matches snapshot 1`] = `
|
|||
]
|
||||
}
|
||||
logoutError={null}
|
||||
schema="
|
||||
{
|
||||
\\"@context\\": \\"http://schema.org\\",
|
||||
\\"@type\\": \\"WebPage\\",
|
||||
\\"description\\": \\"LandingPage.schemaDescription\\",
|
||||
\\"name\\": \\"LandingPage.schemaTitle\\",
|
||||
\\"image\\": [
|
||||
\\"http://localhost:3000/saunatimeFacebook-1200x630.jpg\\"
|
||||
]
|
||||
}
|
||||
"
|
||||
schema={
|
||||
Object {
|
||||
"@context": "http://schema.org",
|
||||
"@type": "WebPage",
|
||||
"description": "LandingPage.schemaDescription",
|
||||
"image": Array [
|
||||
"http://localhost:3000/saunatimeFacebook-1200x630.jpg",
|
||||
],
|
||||
"name": "LandingPage.schemaTitle",
|
||||
}
|
||||
}
|
||||
scrollingDisabled={false}
|
||||
title="LandingPage.schemaTitle"
|
||||
twitterImages={
|
||||
|
|
|
|||
|
|
@ -335,15 +335,13 @@ export class ListingPageComponent extends Component {
|
|||
facebookImages={facebookImages}
|
||||
twitterImages={twitterImages}
|
||||
canonicalPath={canonicalPath}
|
||||
schema={`
|
||||
{
|
||||
"@context": "http://schema.org",
|
||||
"@type": "ItemPage",
|
||||
"description": "${description}",
|
||||
"name": "${schemaTitle}",
|
||||
"image": ${schemaImages}
|
||||
}
|
||||
`}
|
||||
schema={{
|
||||
'@context': 'http://schema.org',
|
||||
'@type': 'ItemPage',
|
||||
description: description,
|
||||
name: schemaTitle,
|
||||
image: schemaImages,
|
||||
}}
|
||||
>
|
||||
{topbar}
|
||||
<div className={listingClasses}>
|
||||
|
|
|
|||
|
|
@ -9,15 +9,15 @@ exports[`ListingPage matches snapshot 1`] = `
|
|||
description="listing1 description"
|
||||
facebookImages={Array []}
|
||||
logoutError={null}
|
||||
schema="
|
||||
{
|
||||
\\"@context\\": \\"http://schema.org\\",
|
||||
\\"@type\\": \\"ItemPage\\",
|
||||
\\"description\\": \\"listing1 description\\",
|
||||
\\"name\\": \\"ListingPage.schemaTitle\\",
|
||||
\\"image\\": []
|
||||
}
|
||||
"
|
||||
schema={
|
||||
Object {
|
||||
"@context": "http://schema.org",
|
||||
"@type": "ItemPage",
|
||||
"description": "listing1 description",
|
||||
"image": "[]",
|
||||
"name": "ListingPage.schemaTitle",
|
||||
}
|
||||
}
|
||||
scrollingDisabled={false}
|
||||
title="ListingPage.schemaTitle"
|
||||
twitterImages={Array []}
|
||||
|
|
|
|||
|
|
@ -276,15 +276,13 @@ export class SearchPageComponent extends Component {
|
|||
scrollingDisabled={scrollingDisabled}
|
||||
description={schemaDescription}
|
||||
title={schemaTitle}
|
||||
schema={`
|
||||
{
|
||||
"@context": "http://schema.org",
|
||||
"@type": "SearchResultsPage",
|
||||
"description": "${schemaDescription}",
|
||||
"name": "${schemaTitle}",
|
||||
"mainEntity": [${schemaMainEntity}]
|
||||
}
|
||||
`}
|
||||
schema={{
|
||||
'@context': 'http://schema.org',
|
||||
'@type': 'SearchResultsPage',
|
||||
description: schemaDescription,
|
||||
name: schemaTitle,
|
||||
mainEntity: [schemaMainEntity],
|
||||
}}
|
||||
>
|
||||
<TopbarContainer className={css.topbar} />
|
||||
<div className={css.container}>
|
||||
|
|
|
|||
|
|
@ -5,15 +5,17 @@ exports[`SearchPageComponent matches snapshot 1`] = `
|
|||
authInfoError={null}
|
||||
description="SearchPage.schemaDescription"
|
||||
logoutError={null}
|
||||
schema="
|
||||
{
|
||||
\\"@context\\": \\"http://schema.org\\",
|
||||
\\"@type\\": \\"SearchResultsPage\\",
|
||||
\\"description\\": \\"SearchPage.schemaDescription\\",
|
||||
\\"name\\": \\"SearchPage.schemaTitle\\",
|
||||
\\"mainEntity\\": [{\\"@type\\":\\"ItemList\\",\\"name\\":\\"SearchPage.schemaMapSearch\\",\\"itemListOrder\\":\\"http://schema.org/ItemListOrderAscending\\",\\"itemListElement\\":[]}]
|
||||
}
|
||||
"
|
||||
schema={
|
||||
Object {
|
||||
"@context": "http://schema.org",
|
||||
"@type": "SearchResultsPage",
|
||||
"description": "SearchPage.schemaDescription",
|
||||
"mainEntity": Array [
|
||||
"{\\"@type\\":\\"ItemList\\",\\"name\\":\\"SearchPage.schemaMapSearch\\",\\"itemListOrder\\":\\"http://schema.org/ItemListOrderAscending\\",\\"itemListElement\\":[]}",
|
||||
],
|
||||
"name": "SearchPage.schemaTitle",
|
||||
}
|
||||
}
|
||||
scrollingDisabled={false}
|
||||
title="SearchPage.schemaTitle"
|
||||
>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue