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

Add JSON-LD Local Business #26

Merged
merged 7 commits into from
Dec 24, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,8 @@ Below you will find a very basic page implementing each of the available JSON-LD
- [Article](#article)
- [Blog](#blog)
- [Course](#course)
- [Local Business](#local-business)
- [Product](#product)
- [Social Profile](#social-profile)

More to follow very, very soon!
Expand Down Expand Up @@ -399,6 +401,63 @@ export default () => (
);
```

### Local Business

Local business is supported with a sub-set of properties.

```jsx
<LocalBusinessJsonLd
type="Store"
id="http://davesdeptstore.example.com"
name="Dave's Department Store"
description="Dave's latest department store in San Jose, now open"
url="http://www.example.com/store-locator/sl/San-Jose-Westgate-Store/1427"
telephone="+14088717984"
address={{
streetAddress: '1600 Saratoga Ave',
addressLocality: 'San Jose',
addressRegion: 'CA',
postalCode: '95129',
addressCountry: 'US',
}}
geo={{
latitude: 37.293058,
timReynolds marked this conversation as resolved.
Show resolved Hide resolved
longitude: -121.988331,
}}
images={[
'https://example.com/photos/1x1/photo.jpg',
'https://example.com/photos/4x3/photo.jpg',
'https://example.com/photos/16x9/photo.jpg',
]}
/>
```

**Required properties**

| Property | Info |
| ------------------------- | -------------------------------------------------------------------------- |
| `@id` | Globally unique ID of the specific business location in the form of a URL. |
| `type` | LocalBusiness or any sub-type |
| `address` | Address of the specific business location |
| `address.addressCountry` | The 2-letter ISO 3166-1 alpha-2 country code |
| `address.addressLocality` | City |
| `address.addressRegion` | State or province, if applicable. |
| `address.postalCode` | Postal or zip code. |
| `address.streetAddress` | Street number, street name, and unit number. |
| `name` | Business name. |

**Supported properties**

| Property | Info |
| --------------- | ----------------------------------------------------------------------------- |
| `description` | Description of the business location |
| `geo` | Geographic coordinates of the business. |
| `geo.latitude` | The latitude of the business location |
| `geo.longitude` | The longitude of the business location |
| `image` | An image or images of the business. |
timReynolds marked this conversation as resolved.
Show resolved Hide resolved
| `telephone` | A business phone number meant to be the primary contact method for customers. |
| `url` | The fully-qualified URL of the specific business location. |

### Product

```jsx
Expand Down
57 changes: 52 additions & 5 deletions e2e/cypress/e2e/jsonld.spec.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { assertSchema } from '@cypress/schema-tools';
import schemas from '../schemas';

const expectedJSONResults = 5;
const expectedJSONResults = 6;

describe('Validates JSON-LD For:', () => {
it('Article', () => {
Expand Down Expand Up @@ -122,12 +122,59 @@ describe('Validates JSON-LD For:', () => {
});
});

it('Product', () => {
it('Local Business', () => {
cy.visit('http://localhost:3000/jsonld');
cy.get('head script[type="application/ld+json"]')
.should('have.length', expectedJSONResults)
.then(tags => {
const jsonLD = JSON.parse(tags[3].innerHTML);
assertSchema(schemas)('Local Business', '1.0.0')(jsonLD);
});
});

it('Local Business', () => {
cy.visit('http://localhost:3000/jsonld');
cy.get('head script[type="application/ld+json"]')
.should('have.length', expectedJSONResults)
.then(tags => {
const jsonLD = JSON.parse(tags[3].innerHTML);
expect(jsonLD).to.deep.equal({
'@context': 'http://schema.org',
'@type': 'Store',
'@id': 'http://davesdeptstore.example.com',
name: "Dave's Department Store",
description: "Dave's latest department store in San Jose, now open",
url:
'http://www.example.com/store-locator/sl/San-Jose-Westgate-Store/1427',
telephone: '+14088717984',
address: {
'@type': 'PostalAddress',
streetAddress: '1600 Saratoga Ave',
addressLocality: 'San Jose',
addressRegion: 'CA',
postalCode: '95129',
addressCountry: 'US',
},
geo: {
'@type': 'GeoCoordinates',
latitude: '37.293058',
longitude: '-121.988331',
},
image: [
'https://example.com/photos/1x1/photo.jpg',
'https://example.com/photos/4x3/photo.jpg',
'https://example.com/photos/16x9/photo.jpg',
],
});
});
});

it('Product', () => {
cy.visit('http://localhost:3000/jsonld');
cy.get('head script[type="application/ld+json"]')
.should('have.length', expectedJSONResults)
.then(tags => {
const jsonLD = JSON.parse(tags[4].innerHTML);
assertSchema(schemas)('Product', '1.0.0')(jsonLD);
});
});
Expand All @@ -137,7 +184,7 @@ describe('Validates JSON-LD For:', () => {
cy.get('head script[type="application/ld+json"]')
.should('have.length', expectedJSONResults)
.then(tags => {
const jsonLD = JSON.parse(tags[3].innerHTML);
const jsonLD = JSON.parse(tags[4].innerHTML);
expect(jsonLD).to.deep.equal({
'@context': 'http://schema.org/',
'@type': 'Product',
Expand Down Expand Up @@ -196,7 +243,7 @@ describe('Validates JSON-LD For:', () => {
cy.get('head script[type="application/ld+json"]')
.should('have.length', expectedJSONResults)
.then(tags => {
const jsonLD = JSON.parse(tags[4].innerHTML);
const jsonLD = JSON.parse(tags[5].innerHTML);
assertSchema(schemas)('Social Profile', '1.0.0')(jsonLD);
});
});
Expand All @@ -206,7 +253,7 @@ describe('Validates JSON-LD For:', () => {
cy.get('head script[type="application/ld+json"]')
.should('have.length', expectedJSONResults)
.then(tags => {
const jsonLD = JSON.parse(tags[4].innerHTML);
const jsonLD = JSON.parse(tags[5].innerHTML);
expect(jsonLD).to.deep.equal({
'@context': 'http://schema.org',
'@type': 'Person',
Expand Down
7 changes: 5 additions & 2 deletions e2e/cypress/schemas/index.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import { combineSchemas } from '@cypress/schema-tools';
import courseVersions from './course-schema';

import articleVersions from './article-schema';
import blogVersions from './blog-schema';
import courseVersions from './course-schema';
import localBusiness from './local-business-schema';
import productVersions from './product-schema';
import socialProfileVersions from './social-profile-schema';

const schemas = combineSchemas(
courseVersions,
articleVersions,
blogVersions,
courseVersions,
localBusiness,
productVersions,
socialProfileVersions,
);
Expand Down
136 changes: 136 additions & 0 deletions e2e/cypress/schemas/local-business-schema.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
import { versionSchemas } from '@cypress/schema-tools';

const socialProfile100 = {
version: {
major: 1,
minor: 0,
patch: 0,
},
schema: {
type: 'object',
title: 'Local Business',
description:
'An example schema describing JSON-LD for type: Local Business',
properties: {
'@context': {
type: 'string',
description: 'Schema.org context',
},
'@type': {
type: 'string',
description:
'Any more specific type supported by Local Business https://schema.org/LocalBusiness',
},
'@id': {
type: 'string',
description:
'Globally unique ID of the specific business location in the form of a URL. The ID should be stable and unchanging over time. Google Search treats the URL as an opaque string and it does not have to be a working link. If the business has multiple locations, make sure the @id is unique for each location.',
},
name: {
type: 'string',
description: 'The name of the person or organisation.',
},
description: {
type: 'string',
description: 'Description for the local business.',
},
url: {
type: 'string',
description:
'The fully-qualified URL of the specific business location. Unlike the @id property, this URL property should be a working link.',
},
telephone: {
type: 'string',
description:
'A business phone number meant to be the primary contact method for customers. Be sure to include the country code and area code in the phone number.',
},
image: {
type: 'array',
items: {
type: 'string',
},
description: "Array of image URL's",
},
address: {
type: 'object',
description: "Array of social profile URL's",
properties: {
'@type': {
type: 'string',
description: 'JSON-LD type: PostalAddress',
},
streetAddress: {
type: 'string',
description: 'Street number, street name, and unit number',
},
addressLocality: {
type: 'string',
description: 'City',
},
addressRegion: {
type: 'string',
description: 'State or province, if applicable.',
},
postalCode: {
type: 'string',
description: 'Postal or zip code.',
},
addressCountry: {
type: 'string',
description: 'The 2-letter ISO 3166-1 alpha-2 country code',
},
},
},
geo: {
type: 'object',
description: "Array of social profile URL's",
properties: {
'@type': {
type: 'string',
description: 'JSON-LD type: GeoCoordinates',
},
latitude: {
type: 'string',
description: 'The latitude of the business location.',
},
longitude: {
type: 'string',
description: 'The longitude of the business location.',
},
},
},
},
required: true,
additionalProperties: false,
},
example: {
'@context': 'http://schema.org',
'@type': 'Store',
image: [
'https://example.com/photos/1x1/photo.jpg',
'https://example.com/photos/4x3/photo.jpg',
'https://example.com/photos/16x9/photo.jpg',
],
'@id': 'http://davesdeptstore.example.com',
name: "Dave's Department Store",
description: 'Some form of description',
address: {
'@type': 'PostalAddress',
streetAddress: '1600 Saratoga Ave',
addressLocality: 'San Jose',
addressRegion: 'CA',
postalCode: '95129',
addressCountry: 'US',
},
geo: {
'@type': 'GeoCoordinates',
latitude: 37.293058,
longitude: -121.988331,
},
url: 'http://www.example.com/store-locator/sl/San-Jose-Westgate-Store/1427',
telephone: '+14088717984',
},
};

const socialProfile = versionSchemas(socialProfile100);
export default socialProfile;
26 changes: 26 additions & 0 deletions e2e/pages/jsonld.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
ArticleJsonLd,
BlogJsonLd,
CourseJsonLd,
LocalBusinessJsonLd,
ProductJsonLd,
SocialProfileJsonLd,
} from '../../dist';
Expand Down Expand Up @@ -48,6 +49,31 @@ export default () => (
description="Course description goes right here"
/>

<LocalBusinessJsonLd
type="Store"
id="http://davesdeptstore.example.com"
name="Dave's Department Store"
description="Dave's latest department store in San Jose, now open"
url="http://www.example.com/store-locator/sl/San-Jose-Westgate-Store/1427"
telephone="+14088717984"
address={{
streetAddress: '1600 Saratoga Ave',
addressLocality: 'San Jose',
addressRegion: 'CA',
postalCode: '95129',
addressCountry: 'US',
}}
geo={{
latitude: 37.293058,
longitude: -121.988331,
}}
images={[
'https://example.com/photos/1x1/photo.jpg',
'https://example.com/photos/4x3/photo.jpg',
'https://example.com/photos/16x9/photo.jpg',
]}
/>

<ProductJsonLd
productName="Executive Anvil"
images={[
Expand Down
2 changes: 2 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import DefaultSeo from './meta/defaultSEO';
import ArticleJsonLd from './jsonld/article';
import BlogJsonLd from './jsonld/blog';
import CourseJsonLd from './jsonld/course';
import LocalBusinessJsonLd from './jsonld/localBusiness';
import ProductJsonLd from './jsonld/product';
import SocialProfileJsonLd from './jsonld/socialProfile';

Expand All @@ -10,6 +11,7 @@ export {
ArticleJsonLd,
BlogJsonLd,
CourseJsonLd,
LocalBusinessJsonLd,
ProductJsonLd,
SocialProfileJsonLd,
};
Loading