Skip to content

Commit ae7923d

Browse files
mkaynakkgarmeeh
andauthored
feat: CustomJsonLd for carousel (#949)
Co-authored-by: Gary Meehan <garymeehan@outlook.com>
1 parent e6c8023 commit ae7923d

File tree

4 files changed

+133
-2
lines changed

4 files changed

+133
-2
lines changed

README.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ If you are using **`pages`** directory then `NextSeo` is **exactly what you need
102102
- [Course](#course-1)
103103
- [Movie](#movie)
104104
- [Recipe](#recipe-1)
105+
- [Custom](#custom)
105106
- [Software App](#software-app)
106107
- [Organization](#organization)
107108
- [Brand](#brand)
@@ -3203,6 +3204,50 @@ export default () => (
32033204
| `instructions.text` | The directions of the instruction step. |
32043205
| `url` | URL of the item's detailed page. |
32053206

3207+
#### Custom
3208+
3209+
```jsx
3210+
import React from 'react';
3211+
import { CarouselJsonLd } from 'next-seo';
3212+
3213+
export default () => (
3214+
<>
3215+
<h1>Carousel Custom JSON-LD</h1>
3216+
<CarouselJsonLd
3217+
ofType="custom"
3218+
url="http://example.com/custom-carousel.html"
3219+
name="Carousel Custom"
3220+
description="Custom Carousel Description"
3221+
data={[
3222+
{
3223+
position: 1,
3224+
type: 'CustomList',
3225+
name: 'Custom 1',
3226+
},
3227+
{
3228+
position: 2,
3229+
type: 'CustomList',
3230+
name: 'Custom 2',
3231+
},
3232+
]}
3233+
/>
3234+
</>
3235+
);
3236+
```
3237+
3238+
**Data Required Properties**
3239+
3240+
| Property | Info |
3241+
| -------- | ----------------- |
3242+
| `type` | Type of the item. |
3243+
| `name` | Name of the item. |
3244+
3245+
**Data Recommended properties**
3246+
3247+
| Property | Info |
3248+
| --------------------- | ------------------------------------------------------------------------- |
3249+
| `position` | Position of the item. If not pass property, it will increase regularly. |
3250+
32063251
### Software App
32073252

32083253
```jsx

cypress/e2e/carousel.spec.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,4 +331,40 @@ describe('Carousel JSON-LD', () => {
331331
expect(jsonLD).to.deep.equal(expectedObject);
332332
});
333333
});
334+
335+
it('Carousel Custom Matches', () => {
336+
cy.visit('http://localhost:3000/carousel-jsonld/custom');
337+
cy.get('head script[type="application/ld+json"]')
338+
.should('have.length', 1)
339+
.then(tags => {
340+
const jsonLD = JSON.parse(tags[0].innerHTML);
341+
const expectedObject = {
342+
'@context': 'https://schema.org',
343+
'@type': 'ItemList',
344+
url: 'http://example.com/custom-carousel.html',
345+
name: 'Carousel Custom',
346+
description: 'Custom Carousel Description',
347+
itemListElement: [
348+
{
349+
'@type': 'ListItem',
350+
position: 1,
351+
item: {
352+
'@type': 'CustomList',
353+
name: 'Custom 1',
354+
},
355+
},
356+
{
357+
'@type': 'ListItem',
358+
position: 2,
359+
item: {
360+
'@type': 'CustomList',
361+
name: 'Custom 2',
362+
},
363+
},
364+
],
365+
};
366+
367+
expect(jsonLD).to.deep.equal(expectedObject);
368+
});
369+
});
334370
});
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import React from 'react';
2+
import { CarouselJsonLd } from '../../../';
3+
import Links from '../../components/links';
4+
5+
const Custom = () => (
6+
<>
7+
<h1>Carousel Custom JSON-LD</h1>
8+
9+
<CarouselJsonLd
10+
ofType="custom"
11+
url="http://example.com/custom-carousel.html"
12+
name="Carousel Custom"
13+
description="Custom Carousel Description"
14+
data={[
15+
{
16+
position: 1,
17+
type: 'CustomList',
18+
name: 'Custom 1',
19+
},
20+
{
21+
position: 2,
22+
type: 'CustomList',
23+
name: 'Custom 2',
24+
},
25+
]}
26+
/>
27+
28+
<Links />
29+
</>
30+
);
31+
32+
export default Custom;

src/jsonld/carousel.tsx

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,21 @@ export interface MovieJsonLdProps {
3737
aggregateRating?: AggregateRating;
3838
}
3939

40+
export interface CustomJsonLdProps {
41+
position?: number;
42+
name: string;
43+
type: string;
44+
}
45+
4046
export interface CarouselJsonLdProps extends JsonLdProps {
41-
ofType: 'default' | 'movie' | 'recipe' | 'course';
47+
ofType: 'default' | 'movie' | 'recipe' | 'course' | 'custom';
4248
data:
4349
| any
4450
| DefaultDataProps[]
4551
| MovieJsonLdProps[]
4652
| ExtendedCourseJsonLdProps[]
47-
| ExtendedRecipeJsonLdProps[];
53+
| ExtendedRecipeJsonLdProps[]
54+
| CustomJsonLdProps[];
4855
}
4956

5057
function CarouselJsonLd({
@@ -147,11 +154,22 @@ function CarouselJsonLd({
147154
},
148155
}),
149156
);
157+
158+
case 'custom':
159+
return (data as CustomJsonLdProps[]).map((item, index) => ({
160+
'@type': 'ListItem',
161+
position: item.position ?? index + 1,
162+
item: {
163+
'@type': item.type,
164+
name: item.name,
165+
},
166+
}));
150167
}
151168
}
152169

153170
const jsonLdData = {
154171
'@type': 'ItemList',
172+
...rest,
155173
itemListElement: generateList(data, ofType),
156174
...rest,
157175
};

0 commit comments

Comments
 (0)