@masters-ws/react-seo 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +138 -0
- package/dist/index.d.mts +351 -0
- package/dist/index.d.ts +351 -0
- package/dist/index.js +1657 -0
- package/dist/index.mjs +1625 -0
- package/package.json +41 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Shammaa
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# @masters-ws/react-seo
|
|
2
|
+
|
|
3
|
+
Professional high-performance SEO package for React and Next.js. **1:1 Feature Parity with the powerful Laravel SEO package.** Designed for high-traffic news sites, e-marketplaces, and professional blog platforms where speed and indexing are critical.
|
|
4
|
+
|
|
5
|
+
## Key Features
|
|
6
|
+
|
|
7
|
+
- ✅ **Hybrid Implementation** - Works with `react-helmet-async` for Client/Pages Router and native `Metadata API` for Next.js App Router.
|
|
8
|
+
- ✅ **Full Metadata Support** - Title, Description, Keywords, Robots, Canonical.
|
|
9
|
+
- ✅ **Intelligent Pagination** - Automatic `rel="prev"` and `rel="next"` handling with clean URL logic.
|
|
10
|
+
- ✅ **Advanced Social Meta** - OpenGraph (Facebook/LinkedIn), Twitter Cards, and WhatsApp/Telegram optimization.
|
|
11
|
+
- ✅ **JSON-LD Schema.org (25+ Types)** - Dedicated components for `NewsArticle`, `Product`, `FAQPage`, `BreadcrumbList`, `Organization`, `WebSite`, `Event`, `HowTo`, `Recipe`, etc.
|
|
12
|
+
- ✅ **Performance & Security** - Support for DNS Prefetch, Preconnect, Preload, and CSP.
|
|
13
|
+
- ✅ **Multilingual Support** - Easy `hreflang` management.
|
|
14
|
+
- ✅ **Mobile Optimized** - Theme color, Apple mobile web app capability, and manifest support.
|
|
15
|
+
- ✅ **Analytics Integration** - Built-in hooks for GA4, GTM, and Facebook Pixel.
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install @masters-ws/react-seo react-helmet-async
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Next.js App Router (SSR - Recommended for News/Malls)
|
|
24
|
+
|
|
25
|
+
For the best performance and 100% server-side rendering, use the `toNextMetadata` adapter in your `layout.tsx` or `page.tsx`.
|
|
26
|
+
|
|
27
|
+
```tsx
|
|
28
|
+
// page.tsx (Server Component)
|
|
29
|
+
import { toNextMetadata } from '@shammaa/react-seo';
|
|
30
|
+
|
|
31
|
+
const config = { name: "My News", url: "https://site.com" };
|
|
32
|
+
|
|
33
|
+
export async function generateMetadata({ params }) {
|
|
34
|
+
const post = await getPost(params.id);
|
|
35
|
+
|
|
36
|
+
return toNextMetadata({
|
|
37
|
+
title: post.title,
|
|
38
|
+
description: post.excerpt,
|
|
39
|
+
type: 'article',
|
|
40
|
+
canonical: `https://site.com/news/${post.slug}`,
|
|
41
|
+
ogImage: post.image,
|
|
42
|
+
publishedTime: post.date,
|
|
43
|
+
readingTime: 5 // Optional: shows in Twitter preview
|
|
44
|
+
}, config);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export default function Page() {
|
|
48
|
+
return <article>...</article>;
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## React / Next.js Pages Router (Client/SSR)
|
|
53
|
+
|
|
54
|
+
### 1. Provider Setup
|
|
55
|
+
Wrap your application in `App.tsx` or `_app.tsx`:
|
|
56
|
+
|
|
57
|
+
```tsx
|
|
58
|
+
import { SEOProvider } from '@shammaa/react-seo';
|
|
59
|
+
|
|
60
|
+
const siteConfig = {
|
|
61
|
+
name: "My Site",
|
|
62
|
+
url: "https://mysite.com",
|
|
63
|
+
googleAnalyticsId: "G-XXXXXXXXXX",
|
|
64
|
+
themeColor: "#007bff"
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
function App({ children }) {
|
|
68
|
+
return (
|
|
69
|
+
<SEOProvider config={siteConfig}>
|
|
70
|
+
{children}
|
|
71
|
+
</SEOProvider>
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### 2. Specialized Components
|
|
77
|
+
|
|
78
|
+
#### News Article
|
|
79
|
+
```tsx
|
|
80
|
+
import { SeoArticle } from '@shammaa/react-seo';
|
|
81
|
+
|
|
82
|
+
<SeoArticle
|
|
83
|
+
article={{
|
|
84
|
+
title: "Article Title",
|
|
85
|
+
description: "Short excerpt...",
|
|
86
|
+
image: "/cover.jpg",
|
|
87
|
+
publishedAt: "2024-02-01T10:00:00Z",
|
|
88
|
+
author: { name: "John Doe" },
|
|
89
|
+
category: "Tech"
|
|
90
|
+
}}
|
|
91
|
+
/>
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
#### FAQ Page
|
|
95
|
+
```tsx
|
|
96
|
+
import { SeoFAQ } from '@shammaa/react-seo';
|
|
97
|
+
|
|
98
|
+
<SeoFAQ
|
|
99
|
+
questions={[
|
|
100
|
+
{ q: "Is it free?", a: "Yes, it is!" },
|
|
101
|
+
{ q: "How to install?", a: "Use npm install." }
|
|
102
|
+
]}
|
|
103
|
+
/>
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Detailed Configuration Reference
|
|
107
|
+
|
|
108
|
+
### SiteConfig Props
|
|
109
|
+
| Prop | Type | Description |
|
|
110
|
+
| :--- | :--- | :--- |
|
|
111
|
+
| `name` | `string` | Site name (used in titles and schemas) |
|
|
112
|
+
| `url` | `string` | Base URL of the site |
|
|
113
|
+
| `logo` | `string` | URL to the site logo |
|
|
114
|
+
| `language` | `string` | Main language (e.g., 'ar', 'en') |
|
|
115
|
+
| `googleAnalyticsId`| `string` | GA4 Measurement ID |
|
|
116
|
+
| `themeColor` | `string` | Browser theme color (mobile) |
|
|
117
|
+
|
|
118
|
+
### SEOData Props (Common)
|
|
119
|
+
| Prop | Type | Description |
|
|
120
|
+
| :--- | :--- | :--- |
|
|
121
|
+
| `title` | `string` | Page title (auto-appends Site name) |
|
|
122
|
+
| `noindex` | `boolean` | Sets robots to noindex and removes canonical |
|
|
123
|
+
| `alternates` | `Array` | List of `{hreflang, href}` for multilingual |
|
|
124
|
+
| `dnsPrefetch` | `string[]` | List of domains to prefetch |
|
|
125
|
+
| `readingTime` | `number` | Reading time in minutes for Twitter Cards |
|
|
126
|
+
|
|
127
|
+
## Advanced Schemas List
|
|
128
|
+
Use these components for specific SEO needs:
|
|
129
|
+
- `<SeoVideo />` - For video content.
|
|
130
|
+
- `<SeoEvent />` - For conferences/events.
|
|
131
|
+
- `<SeoLocalBusiness />` - For physical stores.
|
|
132
|
+
- `<SeoHowTo />` - For tutorials.
|
|
133
|
+
- `<SeoReview />` - For product ratings.
|
|
134
|
+
- `<SeoJobPosting />` - For hiring.
|
|
135
|
+
- `<SeoRecipe />` - For cooking sites.
|
|
136
|
+
|
|
137
|
+
## License
|
|
138
|
+
MIT
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
interface SiteConfig {
|
|
4
|
+
name: string;
|
|
5
|
+
description: string;
|
|
6
|
+
url: string;
|
|
7
|
+
logo?: string;
|
|
8
|
+
publisher?: string;
|
|
9
|
+
twitterHandle?: string;
|
|
10
|
+
facebookAppId?: string;
|
|
11
|
+
language?: string;
|
|
12
|
+
socialLinks?: string[];
|
|
13
|
+
googleAnalyticsId?: string;
|
|
14
|
+
gtmId?: string;
|
|
15
|
+
facebookPixelId?: string;
|
|
16
|
+
yandexMetricaId?: string;
|
|
17
|
+
themeColor?: string;
|
|
18
|
+
manifest?: string;
|
|
19
|
+
}
|
|
20
|
+
interface SEOData {
|
|
21
|
+
title?: string;
|
|
22
|
+
description?: string;
|
|
23
|
+
image?: string;
|
|
24
|
+
canonical?: string;
|
|
25
|
+
type?: 'website' | 'article' | 'product' | 'profile' | 'video' | 'faq';
|
|
26
|
+
robots?: string;
|
|
27
|
+
noindex?: boolean;
|
|
28
|
+
keywords?: string[];
|
|
29
|
+
prev?: string;
|
|
30
|
+
next?: string;
|
|
31
|
+
alternates?: Array<{
|
|
32
|
+
hreflang: string;
|
|
33
|
+
href: string;
|
|
34
|
+
}>;
|
|
35
|
+
ogTitle?: string;
|
|
36
|
+
ogDescription?: string;
|
|
37
|
+
ogImage?: string;
|
|
38
|
+
ogType?: string;
|
|
39
|
+
ogLocale?: string;
|
|
40
|
+
twitterCard?: 'summary' | 'summary_large_image' | 'app' | 'player';
|
|
41
|
+
twitterTitle?: string;
|
|
42
|
+
twitterDescription?: string;
|
|
43
|
+
twitterImage?: string;
|
|
44
|
+
publishedTime?: string;
|
|
45
|
+
modifiedTime?: string;
|
|
46
|
+
author?: {
|
|
47
|
+
name: string;
|
|
48
|
+
url?: string;
|
|
49
|
+
image?: string;
|
|
50
|
+
};
|
|
51
|
+
tags?: string[];
|
|
52
|
+
section?: string;
|
|
53
|
+
readingTime?: number;
|
|
54
|
+
product?: {
|
|
55
|
+
sku?: string;
|
|
56
|
+
brand?: string;
|
|
57
|
+
price?: number;
|
|
58
|
+
currency?: string;
|
|
59
|
+
availability?: string;
|
|
60
|
+
rating?: number;
|
|
61
|
+
reviewCount?: number;
|
|
62
|
+
};
|
|
63
|
+
dnsPrefetch?: string[];
|
|
64
|
+
preconnect?: string[];
|
|
65
|
+
prefetch?: string[];
|
|
66
|
+
preload?: Array<{
|
|
67
|
+
href: string;
|
|
68
|
+
as: string;
|
|
69
|
+
type?: string;
|
|
70
|
+
}>;
|
|
71
|
+
whatsappImage?: string;
|
|
72
|
+
whatsappDescription?: string;
|
|
73
|
+
schema?: any;
|
|
74
|
+
}
|
|
75
|
+
interface BreadcrumbItem {
|
|
76
|
+
name: string;
|
|
77
|
+
item: string;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
interface SEOProviderProps {
|
|
81
|
+
config: SiteConfig;
|
|
82
|
+
children: React.ReactNode;
|
|
83
|
+
helmetContext?: {};
|
|
84
|
+
}
|
|
85
|
+
declare const SEOProvider: React.FC<SEOProviderProps>;
|
|
86
|
+
declare const useSEOConfig: () => SiteConfig;
|
|
87
|
+
|
|
88
|
+
interface SEOProps extends SEOData {
|
|
89
|
+
children?: React.ReactNode;
|
|
90
|
+
}
|
|
91
|
+
declare const SEO: React.FC<SEOProps>;
|
|
92
|
+
|
|
93
|
+
interface BreadcrumbProps {
|
|
94
|
+
items: BreadcrumbItem[];
|
|
95
|
+
className?: string;
|
|
96
|
+
separator?: React.ReactNode;
|
|
97
|
+
renderLink?: (item: BreadcrumbItem, isLast: boolean) => React.ReactNode;
|
|
98
|
+
}
|
|
99
|
+
declare const Breadcrumb: React.FC<BreadcrumbProps>;
|
|
100
|
+
|
|
101
|
+
interface SeoArticleProps extends Omit<SEOProps, 'type'> {
|
|
102
|
+
article: {
|
|
103
|
+
title: string;
|
|
104
|
+
description: string;
|
|
105
|
+
image: string;
|
|
106
|
+
publishedAt: string;
|
|
107
|
+
updatedAt?: string;
|
|
108
|
+
author: {
|
|
109
|
+
name: string;
|
|
110
|
+
url?: string;
|
|
111
|
+
};
|
|
112
|
+
category?: string;
|
|
113
|
+
tags?: string[];
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
declare const SeoArticle: React.FC<SeoArticleProps>;
|
|
117
|
+
|
|
118
|
+
interface SeoProductProps extends Omit<SEOProps, 'type' | 'product'> {
|
|
119
|
+
item: {
|
|
120
|
+
name: string;
|
|
121
|
+
description: string;
|
|
122
|
+
image: string;
|
|
123
|
+
sku?: string;
|
|
124
|
+
brand?: string;
|
|
125
|
+
price: number;
|
|
126
|
+
currency: string;
|
|
127
|
+
availability?: string;
|
|
128
|
+
rating?: number;
|
|
129
|
+
reviewCount?: number;
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
declare const SeoProduct: React.FC<SeoProductProps>;
|
|
133
|
+
|
|
134
|
+
interface FAQItem {
|
|
135
|
+
question: string;
|
|
136
|
+
answer: string;
|
|
137
|
+
}
|
|
138
|
+
interface SeoFAQProps {
|
|
139
|
+
items: FAQItem[];
|
|
140
|
+
}
|
|
141
|
+
declare const SeoFAQ: React.FC<SeoFAQProps>;
|
|
142
|
+
|
|
143
|
+
interface SeoVideoProps {
|
|
144
|
+
video: {
|
|
145
|
+
name: string;
|
|
146
|
+
description: string;
|
|
147
|
+
thumbnailUrl: string[] | string;
|
|
148
|
+
uploadDate: string;
|
|
149
|
+
contentUrl?: string;
|
|
150
|
+
embedUrl?: string;
|
|
151
|
+
duration?: string;
|
|
152
|
+
interactionStatistic?: {
|
|
153
|
+
viewCount?: number;
|
|
154
|
+
};
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
declare const SeoVideo: React.FC<SeoVideoProps>;
|
|
158
|
+
|
|
159
|
+
interface SeoEventProps {
|
|
160
|
+
event: {
|
|
161
|
+
name: string;
|
|
162
|
+
description: string;
|
|
163
|
+
startDate: string;
|
|
164
|
+
endDate?: string;
|
|
165
|
+
eventStatus?: 'EventCancelled' | 'EventMovedOnline' | 'EventPostponed' | 'EventRescheduled' | 'EventScheduled';
|
|
166
|
+
eventAttendanceMode?: 'OfflineEventAttendanceMode' | 'OnlineEventAttendanceMode' | 'MixedEventAttendanceMode';
|
|
167
|
+
location: {
|
|
168
|
+
name: string;
|
|
169
|
+
address?: string;
|
|
170
|
+
url?: string;
|
|
171
|
+
};
|
|
172
|
+
image?: string[] | string;
|
|
173
|
+
offers?: {
|
|
174
|
+
price: number;
|
|
175
|
+
priceCurrency: string;
|
|
176
|
+
url?: string;
|
|
177
|
+
availability?: string;
|
|
178
|
+
};
|
|
179
|
+
organizer?: {
|
|
180
|
+
name: string;
|
|
181
|
+
url?: string;
|
|
182
|
+
};
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
declare const SeoEvent: React.FC<SeoEventProps>;
|
|
186
|
+
|
|
187
|
+
interface SeoLocalBusinessProps {
|
|
188
|
+
business: {
|
|
189
|
+
type?: string;
|
|
190
|
+
name: string;
|
|
191
|
+
image?: string[] | string;
|
|
192
|
+
description?: string;
|
|
193
|
+
id?: string;
|
|
194
|
+
url?: string;
|
|
195
|
+
telephone?: string;
|
|
196
|
+
address: {
|
|
197
|
+
streetAddress: string;
|
|
198
|
+
addressLocality: string;
|
|
199
|
+
addressRegion?: string;
|
|
200
|
+
postalCode?: string;
|
|
201
|
+
addressCountry: string;
|
|
202
|
+
};
|
|
203
|
+
geo?: {
|
|
204
|
+
latitude: number;
|
|
205
|
+
longitude: number;
|
|
206
|
+
};
|
|
207
|
+
openingHours?: string[] | string;
|
|
208
|
+
priceRange?: string;
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
declare const SeoLocalBusiness: React.FC<SeoLocalBusinessProps>;
|
|
212
|
+
|
|
213
|
+
interface SeoCategoryProps extends Omit<SEOProps, 'type'> {
|
|
214
|
+
category: {
|
|
215
|
+
name: string;
|
|
216
|
+
description: string;
|
|
217
|
+
image?: string;
|
|
218
|
+
url: string;
|
|
219
|
+
};
|
|
220
|
+
page?: number;
|
|
221
|
+
totalPage?: number;
|
|
222
|
+
}
|
|
223
|
+
declare const SeoCategory: React.FC<SeoCategoryProps>;
|
|
224
|
+
|
|
225
|
+
interface SeoTagProps extends Omit<SEOProps, 'type'> {
|
|
226
|
+
tag: {
|
|
227
|
+
name: string;
|
|
228
|
+
description?: string;
|
|
229
|
+
url: string;
|
|
230
|
+
};
|
|
231
|
+
page?: number;
|
|
232
|
+
totalPage?: number;
|
|
233
|
+
}
|
|
234
|
+
declare const SeoTag: React.FC<SeoTagProps>;
|
|
235
|
+
|
|
236
|
+
interface SeoAuthorProps extends Omit<SEOProps, 'type'> {
|
|
237
|
+
author: {
|
|
238
|
+
name: string;
|
|
239
|
+
description?: string;
|
|
240
|
+
image?: string;
|
|
241
|
+
url: string;
|
|
242
|
+
jobTitle?: string;
|
|
243
|
+
};
|
|
244
|
+
page?: number;
|
|
245
|
+
totalPage?: number;
|
|
246
|
+
}
|
|
247
|
+
declare const SeoAuthor: React.FC<SeoAuthorProps>;
|
|
248
|
+
|
|
249
|
+
interface HowToStep {
|
|
250
|
+
name: string;
|
|
251
|
+
text: string;
|
|
252
|
+
image?: string;
|
|
253
|
+
url?: string;
|
|
254
|
+
}
|
|
255
|
+
interface SeoHowToProps {
|
|
256
|
+
name: string;
|
|
257
|
+
description?: string;
|
|
258
|
+
image?: string;
|
|
259
|
+
steps: HowToStep[] | string[];
|
|
260
|
+
}
|
|
261
|
+
declare const SeoHowTo: React.FC<SeoHowToProps>;
|
|
262
|
+
|
|
263
|
+
interface SeoReviewProps {
|
|
264
|
+
itemReviewed: {
|
|
265
|
+
type: string;
|
|
266
|
+
name: string;
|
|
267
|
+
image?: string;
|
|
268
|
+
};
|
|
269
|
+
review: {
|
|
270
|
+
author: string;
|
|
271
|
+
datePublished?: string;
|
|
272
|
+
reviewBody: string;
|
|
273
|
+
ratingValue: number;
|
|
274
|
+
bestRating?: number;
|
|
275
|
+
worstRating?: number;
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
declare const SeoReview: React.FC<SeoReviewProps>;
|
|
279
|
+
|
|
280
|
+
interface SeoCourseProps {
|
|
281
|
+
course: {
|
|
282
|
+
name: string;
|
|
283
|
+
description: string;
|
|
284
|
+
providerName: string;
|
|
285
|
+
providerUrl?: string;
|
|
286
|
+
image?: string;
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
declare const SeoCourse: React.FC<SeoCourseProps>;
|
|
290
|
+
|
|
291
|
+
interface SeoRecipeProps {
|
|
292
|
+
recipe: {
|
|
293
|
+
name: string;
|
|
294
|
+
description: string;
|
|
295
|
+
image: string[] | string;
|
|
296
|
+
author: string;
|
|
297
|
+
publishedDate?: string;
|
|
298
|
+
prepTime?: string;
|
|
299
|
+
cookTime?: string;
|
|
300
|
+
totalTime?: string;
|
|
301
|
+
recipeYield?: string;
|
|
302
|
+
recipeCategory?: string;
|
|
303
|
+
recipeCuisine?: string;
|
|
304
|
+
ingredients: string[];
|
|
305
|
+
instructions: Array<{
|
|
306
|
+
name?: string;
|
|
307
|
+
text: string;
|
|
308
|
+
image?: string;
|
|
309
|
+
}>;
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
declare const SeoRecipe: React.FC<SeoRecipeProps>;
|
|
313
|
+
|
|
314
|
+
interface SeoJobPostingProps {
|
|
315
|
+
job: {
|
|
316
|
+
title: string;
|
|
317
|
+
description: string;
|
|
318
|
+
datePosted: string;
|
|
319
|
+
validThrough?: string;
|
|
320
|
+
employmentType?: string | string[];
|
|
321
|
+
hiringOrganization: {
|
|
322
|
+
name: string;
|
|
323
|
+
sameAs?: string;
|
|
324
|
+
logo?: string;
|
|
325
|
+
};
|
|
326
|
+
jobLocation: {
|
|
327
|
+
streetAddress: string;
|
|
328
|
+
addressLocality: string;
|
|
329
|
+
addressRegion?: string;
|
|
330
|
+
postalCode?: string;
|
|
331
|
+
addressCountry: string;
|
|
332
|
+
};
|
|
333
|
+
baseSalary?: {
|
|
334
|
+
currency: string;
|
|
335
|
+
value: number | {
|
|
336
|
+
minValue: number;
|
|
337
|
+
maxValue: number;
|
|
338
|
+
};
|
|
339
|
+
unitText?: string;
|
|
340
|
+
};
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
declare const SeoJobPosting: React.FC<SeoJobPostingProps>;
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* Converts SEOData and SiteConfig to a Next.js compatible Metadata object.
|
|
347
|
+
* This is designed to be used in Server Components (App Router).
|
|
348
|
+
*/
|
|
349
|
+
declare function toNextMetadata(props: SEOData, config: SiteConfig): any;
|
|
350
|
+
|
|
351
|
+
export { Breadcrumb, type BreadcrumbItem, type BreadcrumbProps, type FAQItem, type HowToStep, SEO, type SEOData, type SEOProps, SEOProvider, type SEOProviderProps, SeoArticle, type SeoArticleProps, SeoAuthor, type SeoAuthorProps, SeoCategory, type SeoCategoryProps, SeoCourse, type SeoCourseProps, SeoEvent, type SeoEventProps, SeoFAQ, type SeoFAQProps, SeoHowTo, type SeoHowToProps, SeoJobPosting, type SeoJobPostingProps, SeoLocalBusiness, type SeoLocalBusinessProps, SeoProduct, type SeoProductProps, SeoRecipe, type SeoRecipeProps, SeoReview, type SeoReviewProps, SeoTag, type SeoTagProps, SeoVideo, type SeoVideoProps, type SiteConfig, toNextMetadata, useSEOConfig };
|