Skip to content

Commit

Permalink
feature: add ParkJsonLd component (#1291)
Browse files Browse the repository at this point in the history
  • Loading branch information
ryanmercadante committed Oct 28, 2023
1 parent f8b907f commit d403076
Show file tree
Hide file tree
Showing 8 changed files with 408 additions and 0 deletions.
87 changes: 87 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ If you are using **`pages`** directory then `NextSeo` is **exactly what you need
- [Product](#product)
- [Social Profile](#social-profile)
- [News Article](#news-article)
- [Park](#park)
- [Video](#video-1)
- [VideoGame](#videogame)
- [Event](#event)
Expand Down Expand Up @@ -1100,6 +1101,7 @@ Below you will find a very basic page implementing each of the available JSON-LD
- [Product](#product)
- [Social Profile](#social-profile)
- [News Article](#news-article)
- [Park](#park)

Pull request very welcome to add any from the list [found on here](https://developers.google.com/search/docs/data-types/article)

Expand Down Expand Up @@ -2136,6 +2138,91 @@ const Page = () => (
export default Page;
```

### Park

```jsx
import { ParkJsonLd } from 'next-seo';

const Page = () => (
<>
<h1>Park JSON-LD</h1>
<ParkJsonLd
id="https://www.example.com/park/minnewaska-state-park"
name="Minnewaska State Park"
url="https://www.example.com/park"
telephone="+18452550752"
images={['https://example.com/photos/1x1/photo.jpg']}
address={{
streetAddress: '5281 Route 44-55',
addressLocality: 'Kerhonkson',
addressRegion: 'NY',
postalCode: '12446',
addressCountry: 'US',
}}
description="A wonderful description about Minnewaska State Park"
geo={{
latitude: '41.735149',
longitude: '-74.239037',
}}
openingHours={[
{
opens: '09:00',
closes: '18:00',
dayOfWeek: [
'Monday',
'Tuesday',
'Wednesday',
'Thursday',
'Friday',
'Saturday',
'Sunday',
],
validFrom: '2019-12-23',
validThrough: '2020-04-02',
},
]}
/>
</>
);

export default Page;
```

**Required properties**

| Property | Info |
| ------------------------- | ------------------------------------------------------------- |
| `@id` | Globally unique ID of the specific park in the form of a URL. |
| `address` | Address of the specific park 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` | Park name. |
| `description` | Park description. |

**Supported properties**

| Property | Info |
| --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| `geo` | Geographic coordinates of the park. |
| `geo.latitude` | The latitude of the park location |
| `geo.longitude` | The longitude of the park location |
| `images` | An image or images of the park. Required for valid markup depending on the type |
| `telephone` | A business phone number meant to be the primary contact method for customers. |
| `url` | The fully-qualified URL of the specific park. |
| `openingHours` | Opening hour specification of the park. You can provide this as a single object, or an array of objects with the properties below. |
| `openingHours.opens` | The opening hour of the place or service on the given day(s) of the week. |
| `openingHours.closes` | The closing hour of the place or service on the given day(s) of the week. |
| `openingHours.dayOfWeek` | The day of the week for which these opening hours are valid. Can be a string or array of strings. Refer to [DayOfWeek](https://schema.org/DayOfWeek) |
| `openingHours.validFrom` | The date when the item becomes valid. |
| `openingHours.validThrough` | The date after when the item is not valid. |
| `isAccessibleForFree` | Whether or not the park is accessible for free. |

**Other**
| `useAppDir` | This should be set to true if using new app directory. Not required if outside of app directory. |

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

### Video
Expand Down
61 changes: 61 additions & 0 deletions cypress/e2e/park.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { assertSchema } from '@cypress/schema-tools';
import schemas from '../schemas';

describe('Park JSON-LD', () => {
it('matches schema', () => {
cy.visit('http://localhost:3000/jsonld/park');
cy.get('head script[type="application/ld+json"]').then(tags => {
const jsonLD = JSON.parse(tags[0].innerHTML);
console.log('jsonLD', jsonLD);
assertSchema(schemas)('Park', '1.0.0')(jsonLD);
});
});

it('renders with all props', () => {
cy.visit('http://localhost:3000/jsonld/park');
cy.get('head script[type="application/ld+json"]').then(tags => {
const jsonLD = JSON.parse(tags[0].innerHTML);
expect(jsonLD).to.deep.equal({
'@context': 'https://schema.org',
'@type': 'Park',
'@id': 'https://www.example.com/park/minnewaska-state-park',
name: 'Minnewaska State Park',
description: 'Description about Minnewaska State Park',
url: 'https://www.example.com/park',
telephone: '+18452550752',
image: ['https://example.com/photos/1x1/photo.jpg'],
address: {
'@type': 'PostalAddress',
streetAddress: '5281 Route 44-55',
addressLocality: 'Kerhonkson',
addressRegion: 'NY',
postalCode: '12446',
addressCountry: 'US',
},
geo: {
latitude: '41.735149',
longitude: '-74.239037',
'@type': 'GeoCoordinates',
},
openingHoursSpecification: [
{
opens: '09:00',
closes: '18:00',
dayOfWeek: [
'Monday',
'Tuesday',
'Wednesday',
'Thursday',
'Friday',
'Saturday',
'Sunday',
],
validFrom: '2019-12-23',
validThrough: '2020-04-02',
'@type': 'OpeningHoursSpecification',
},
],
});
});
});
});
2 changes: 2 additions & 0 deletions cypress/schemas/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import webPageVersions from './web-page-schema';
import videoVersions from './video-schema';
import howToVersions from './how-to-schema';
import imageVersions from './image-schema';
import parkVersions from './park-schema';

const schemas = combineSchemas(
articleVersions,
Expand Down Expand Up @@ -56,5 +57,6 @@ const schemas = combineSchemas(
videoVersions,
howToVersions,
imageVersions,
parkVersions,
);
export default schemas;
164 changes: 164 additions & 0 deletions cypress/schemas/park-schema.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
import { versionSchemas } from '@cypress/schema-tools';

import address100 from './address';

const park100 = {
version: {
major: 1,
minor: 0,
patch: 0,
},
schema: {
type: 'object',
title: 'Park',
description: 'An example schema describing JSON-LD for type: Park',
properties: {
'@context': {
type: 'string',
description: 'Schema.org context',
},
'@type': {
type: 'string',
description:
'Any more specific type supported by Park https://schema.org/Park',
},
'@id': {
type: 'string',
description:
'Globally unique ID of the specific park 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.',
},
name: {
type: 'string',
description: 'The name of the park.',
},
description: {
type: 'string',
description: 'Description for the park.',
},
url: {
type: 'string',
description:
'The fully-qualified URL of the specific park location. Unlike the @id property, this URL property should be a working link.',
},
telephone: {
type: 'string',
description:
'A park 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: {
...address100.schema,
see: address100,
},
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 park location.',
},
longitude: {
type: 'string',
description: 'The longitude of the park location.',
},
},
},
openingHoursSpecification: {
type: 'array',
description: 'Opening hour specification for the park',
item: {
type: 'object',
properties: {
'@type': {
type: 'string',
description: 'JSON-LD type: OpeningHoursSpecification',
},
opens: {
type: 'string',
description:
'The opening hour of the place or service on the given day(s) of the week.',
},
closes: {
type: 'string',
description:
'The closing hour of the place or service on the given day(s) of the week.',
},
dayOfWeek: {
type: 'array',
items: {
type: 'string',
},
description:
'The day of the week for which these opening hours are valid.',
},
validFrom: {
type: 'string',
description: 'The date when the item becomes valid.',
},
validThrough: {
type: 'string',
description: 'The date after when the item is not valid.',
},
},
},
},
},
required: true,
additionalProperties: false,
},
example: {
'@context': 'https://schema.org',
'@type': 'Park',
'@id': 'https://www.example.com/park/minnewaska-state-park',
name: 'Minnewaska State Park',
description: 'Description about Minnewaska State Park',
url: 'https://www.example.com/park',
telephone: '+18452550752',
image: ['https://example.com/photos/1x1/photo.jpg'],
address: {
'@type': 'PostalAddress',
streetAddress: '5281 Route 44-55',
addressLocality: 'Kerhonkson',
addressRegion: 'NY',
postalCode: '12446',
addressCountry: 'US',
},
geo: {
latitude: '41.735149',
longitude: '-74.239037',
'@type': 'GeoCoordinates',
},
openingHoursSpecification: [
{
opens: '09:00',
closes: '18:00',
dayOfWeek: [
'Monday',
'Tuesday',
'Wednesday',
'Thursday',
'Friday',
'Saturday',
'Sunday',
],
validFrom: '2019-12-23',
validThrough: '2020-04-02',
'@type': 'OpeningHoursSpecification',
},
],
},
};

const park = versionSchemas(park100);
export default park;
1 change: 1 addition & 0 deletions e2e/pages/jsonld/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const allJsonLDPages = [
'logo',
'newsarticle',
'organization',
'park',
'product',
'profilePage',
'qaPage',
Expand Down

0 comments on commit d403076

Please sign in to comment.