Skip to content

Commit

Permalink
feat: add EventJsonLd component (garmeeh#149)
Browse files Browse the repository at this point in the history
  • Loading branch information
kenleytomlin authored Feb 3, 2020
1 parent bd03bcb commit f1c1f09
Show file tree
Hide file tree
Showing 12 changed files with 346 additions and 60 deletions.
51 changes: 51 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ Version One docs can be found [here](https://github.com/garmeeh/next-seo/tree/su
- [Product](#product)
- [Social Profile](#social-profile)
- [News Article](#news-article)
- [Event](#event)
- [Contributors](#contributors)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->
Expand Down Expand Up @@ -1391,6 +1392,56 @@ export default () => (

[Google Docs for Social Profile](https://developers.google.com/search/docs/data-types/social-profile)

### Event

```jsx
import React from 'react';
import { EventJsonLd } from 'next-seo';

export default () => (
<>
<h1>Event JSON-LD</h1>
<EventJsonLd
name="My Event"
startDate="2020-01-23T00:00:00.000Z"
endDate="2020-01-24T00:00:00.000Z"
location={{
name: 'My Place',
sameAs: 'https://example.com/my-place',
address: {
streetAddress: '1600 Saratoga Ave',
addressLocality: 'San Jose',
addressRegion: 'CA',
postalCode: '95129',
addressCountry: 'US',
},
}}
url="https://example.com/my-event"
images={['https://example.com/photos/photo.jpg']}
description="My event @ my place"
/>
</>
);
```

**Required properties**

| Property | Info |
| ----------- | -------------------------------------------------- |
| `name` | The name of the event |
| `startDate` | The start date time of the event in iso8601 format |
| `endDate` | The end date time of the event in iso8601 format |
| `location` | Place type with a nested Address type |

**Supported properties**

| Property | Info |
| ----------------- | ------------------------------------- |
| `description` | Description of the event |
| `location.sameAs` | Description of the event location |
| `images` | An image or images of the event. |
| `url` | The fully-qualified URL of the event. |

## Contributors

Thanks goes to these wonderful people ([emoji key](https://github.com/kentcdodds/all-contributors#emoji-key)):
Expand Down
45 changes: 44 additions & 1 deletion 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 = 12;
const expectedJSONResults = 13;

const articleLdJsonIndex = 0;
const breadcrumbLdJsonIndex = 1;
Expand All @@ -15,6 +15,7 @@ const corporateContactIndex = 8;
const newsarticleLdJsonIndex = 9;
const faqPageLdJsonIndex = 10;
const jobPostingLdJsonIndex = 11;
const eventLdJsonIndex = 12;

describe('Validates JSON-LD For:', () => {
it('Article', () => {
Expand Down Expand Up @@ -602,4 +603,46 @@ describe('Validates JSON-LD For:', () => {
});
});
});

it('Event', () => {
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[eventLdJsonIndex].innerHTML);
assertSchema(schemas)('Event', '1.0.0')(jsonLD);
});
});

it('Event Matches', () => {
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[eventLdJsonIndex].innerHTML);
expect(jsonLD).to.deep.equal({
'@context': 'http://schema.org',
'@type': 'Event',
name: 'My Event',
startDate: '2020-01-23T00:00:00.000Z',
endDate: '2020-01-24T00:00:00.000Z',
url: 'https://example.com/my-event',
location: {
'@type': 'Place',
name: 'My Place',
address: {
'@type': 'PostalAddress',
streetAddress: '1600 Saratoga Ave',
addressLocality: 'San Jose',
addressRegion: 'CA',
postalCode: '95129',
addressCountry: 'US',
},
sameAs: 'https://example.com/my-place',
},
image: ['https://example.com/photos/photo.jpg'],
description: 'My event @ my place',
});
});
});
});
50 changes: 50 additions & 0 deletions cypress/schemas/address.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { versionSchemas } from '@cypress/schema-tools';

const address100 = {
version: {
major: 1,
minor: 0,
patch: 0,
},
schema: {
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',
},
},
},
example: {
'@type': 'PostalAddress',
streetAddress: '1600 Saratoga Ave',
addressLocality: 'San Jose',
addressRegion: 'CA',
postalCode: '95129',
addressCountry: 'US',
},
};

const address = versionSchemas(address100);
export default address;
81 changes: 81 additions & 0 deletions cypress/schemas/event-schema.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { versionSchemas } from '@cypress/schema-tools';

import address100 from './address';

const location100 = {
version: {
major: 1,
minor: 0,
patch: 0,
},
schema: {
type: 'object',
description: 'Location',
properties: {
'@type': {
type: 'string',
description: 'Location type',
},
name: {
type: 'string',
description: 'Location name',
},
address: {
...address100.schema,
see: address100,
},
},
},
example: {
'@type': 'Place',
name: 'My place',
address: address100.example,
},
};

const event100 = {
version: {
major: 1,
minor: 0,
patch: 0,
},
schema: {
type: 'object',
title: 'Event',
properties: {
'@type': {
type: 'string',
description: 'Event type',
},
name: {
type: 'string',
description: 'Event name',
},
startDate: {
type: 'string',
description: 'Event start date',
},
endDate: {
type: 'string',
description: 'Event end date',
},
location: {
...location100.schema,
see: location100,
},
},
},
example: {
'@context': 'http://schema.org',
'@type': 'Event',
name: 'My event',
startDate: '2020-01-23T00:00:00.000Z',
endDate: '2020-02-24T00:00:00.000Z',
location: location.example,
image: ['https://example.com/photos/1x1/photo.jpg'],
description: 'My event @ my place',
},
};

const event = versionSchemas(event100);
export default event;
2 changes: 2 additions & 0 deletions cypress/schemas/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import corporateContactVersions from './corporate-contact-schema';
import newsarticleVersions from './newsarticle-schema';
import faqPageVersion from './faq-page-schema';
import jobPostingVersions from './job-posting-schema';
import eventVersion from './event-schema';

const schemas = combineSchemas(
articleVersions,
Expand All @@ -26,5 +27,6 @@ const schemas = combineSchemas(
newsarticleVersions,
faqPageVersion,
jobPostingVersions,
eventVersion,
);
export default schemas;
41 changes: 5 additions & 36 deletions cypress/schemas/local-business-schema.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { versionSchemas } from '@cypress/schema-tools';

import address100 from './address';

const localBusiness110 = {
version: {
major: 1,
Expand Down Expand Up @@ -52,34 +54,8 @@ const localBusiness110 = {
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',
},
},
...address100.schema,
see: address100,
},
geo: {
type: 'object',
Expand Down Expand Up @@ -160,14 +136,7 @@ const localBusiness110 = {
'@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',
},
address: address100.example,
geo: {
'@type': 'GeoCoordinates',
latitude: '37.293058',
Expand Down
20 changes: 20 additions & 0 deletions e2e/pages/jsonld.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
NewsArticleJsonLd,
FAQPageJsonLd,
JobPostingJsonLd,
EventJsonLd,
} from '../../lib';
import Links from '../components/links';

Expand Down Expand Up @@ -278,6 +279,25 @@ export default () => (
applicantLocationRequirements="FR"
/>

<EventJsonLd
name="My Event"
startDate="2020-01-23T00:00:00.000Z"
endDate="2020-01-24T00:00:00.000Z"
location={{
name: 'My Place',
sameAs: 'https://example.com/my-place',
address: {
streetAddress: '1600 Saratoga Ave',
addressLocality: 'San Jose',
addressRegion: 'CA',
postalCode: '95129',
addressCountry: 'US',
},
}}
url="https://example.com/my-event"
images={['https://example.com/photos/photo.jpg']}
description="My event @ my place"
/>
<Links />
</>
);
1 change: 1 addition & 0 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,6 @@ export {
default as NewsArticleJsonLd,
NewsArticleJsonLdProps,
} from './jsonld/newsarticle';
export { default as EventJsonLd, EventJsonLdProps } from './jsonld/event';

export { DefaultSeoProps, NextSeoProps } from './types';
Loading

0 comments on commit f1c1f09

Please sign in to comment.