@cavuno/board 1.31.0 → 1.33.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/dist/{board--nLjpneU.d.ts → board-0yI5ZRJw.d.ts} +1 -1
- package/dist/{board-BS8Ax7hz.d.mts → board-BTVapQiL.d.mts} +1 -1
- package/dist/filters.d.mts +11 -11
- package/dist/filters.d.ts +11 -11
- package/dist/filters.js +590 -6
- package/dist/filters.mjs +590 -6
- package/dist/format.d.mts +12 -7
- package/dist/format.d.ts +12 -7
- package/dist/format.js +561 -3
- package/dist/format.mjs +561 -3
- package/dist/index.d.mts +11 -6
- package/dist/index.d.ts +11 -6
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{jobs-Dmz8uexp.d.mts → jobs-Di4AV-02.d.mts} +6 -0
- package/dist/{jobs-Dmz8uexp.d.ts → jobs-Di4AV-02.d.ts} +6 -0
- package/dist/{salaries-CrtQBy81.d.ts → salaries-B-zJKjkk.d.ts} +1 -1
- package/dist/{salaries-QXFAyysR.d.mts → salaries-D-BGZpDC.d.mts} +1 -1
- package/dist/seo.d.mts +9 -16
- package/dist/seo.d.ts +9 -16
- package/dist/seo.js +497 -7
- package/dist/seo.mjs +497 -7
- package/dist/server.d.mts +3 -3
- package/dist/server.d.ts +3 -3
- package/dist/sitemap.d.mts +3 -3
- package/dist/sitemap.d.ts +3 -3
- package/dist/theme.js +7 -1
- package/dist/theme.mjs +7 -1
- package/dist/ui-copy-rlfoH9P3.d.mts +232 -0
- package/dist/ui-copy-rlfoH9P3.d.ts +232 -0
- package/package.json +1 -1
- package/skills/manifest.json +1 -1
|
@@ -2421,6 +2421,12 @@ interface components {
|
|
|
2421
2421
|
} | null;
|
|
2422
2422
|
/** @description Operator-defined custom job-field definitions (CAV-294), in display order. Board-wide; the frontend uses these to render and localize each job's opaque `customFieldValues`. Empty when the board defines none. Display-only — not filterable or searchable in v1. */
|
|
2423
2423
|
customFields: components["schemas"]["CustomFieldDefinition"][];
|
|
2424
|
+
/** @description Stored operator label overrides by config group (`jobCardLabels`, `navLabels`, `breadcrumbsLabels`, …) — plain-text chrome copy to merge over the `@cavuno/board` `uiCopy(language)` catalog via `uiCopy(language, labels)` (ADR-0059). Empty object when the board stores none. */
|
|
2425
|
+
labels: {
|
|
2426
|
+
[key: string]: {
|
|
2427
|
+
[key: string]: string;
|
|
2428
|
+
};
|
|
2429
|
+
};
|
|
2424
2430
|
};
|
|
2425
2431
|
PublicCompaniesSearchBody: {
|
|
2426
2432
|
/** @description Free-text search query matched against company name. Up to 200 characters. */
|
|
@@ -2421,6 +2421,12 @@ interface components {
|
|
|
2421
2421
|
} | null;
|
|
2422
2422
|
/** @description Operator-defined custom job-field definitions (CAV-294), in display order. Board-wide; the frontend uses these to render and localize each job's opaque `customFieldValues`. Empty when the board defines none. Display-only — not filterable or searchable in v1. */
|
|
2423
2423
|
customFields: components["schemas"]["CustomFieldDefinition"][];
|
|
2424
|
+
/** @description Stored operator label overrides by config group (`jobCardLabels`, `navLabels`, `breadcrumbsLabels`, …) — plain-text chrome copy to merge over the `@cavuno/board` `uiCopy(language)` catalog via `uiCopy(language, labels)` (ADR-0059). Empty object when the board stores none. */
|
|
2425
|
+
labels: {
|
|
2426
|
+
[key: string]: {
|
|
2427
|
+
[key: string]: string;
|
|
2428
|
+
};
|
|
2429
|
+
};
|
|
2424
2430
|
};
|
|
2425
2431
|
PublicCompaniesSearchBody: {
|
|
2426
2432
|
/** @description Free-text search query matched against company name. Up to 200 characters. */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { b as Schemas, L as ListEnvelope, m as RelatedSearch } from './jobs-
|
|
1
|
+
import { b as Schemas, L as ListEnvelope, m as RelatedSearch } from './jobs-Di4AV-02.js';
|
|
2
2
|
|
|
3
3
|
/** Author shape embedded on posts (no `object` discriminator). */
|
|
4
4
|
type BlogAuthorEmbed = Schemas['PublicBlogAuthorEmbed'];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { b as Schemas, L as ListEnvelope, m as RelatedSearch } from './jobs-
|
|
1
|
+
import { b as Schemas, L as ListEnvelope, m as RelatedSearch } from './jobs-Di4AV-02.mjs';
|
|
2
2
|
|
|
3
3
|
/** Author shape embedded on posts (no `object` discriminator). */
|
|
4
4
|
type BlogAuthorEmbed = Schemas['PublicBlogAuthorEmbed'];
|
package/dist/seo.d.mts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { P as PublicBlogPostSummary, B as BlogAuthorEmbed, C as CompanyCategorySalary, a as CompanySalary, L as LocationSalaryDetail, S as SkillSalaryDetail, T as TitleSalaryDetail } from './salaries-
|
|
2
|
-
import { P as PublicBoard } from './board-
|
|
3
|
-
import { P as PublicJob } from './jobs-
|
|
1
|
+
import { P as PublicBlogPostSummary, B as BlogAuthorEmbed, C as CompanyCategorySalary, a as CompanySalary, L as LocationSalaryDetail, S as SkillSalaryDetail, T as TitleSalaryDetail } from './salaries-D-BGZpDC.mjs';
|
|
2
|
+
import { P as PublicBoard } from './board-BTVapQiL.mjs';
|
|
3
|
+
import { P as PublicJob } from './jobs-Di4AV-02.mjs';
|
|
4
|
+
import { B as BoardLabelOverrides } from './ui-copy-rlfoH9P3.mjs';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Google for Jobs `JobPosting` structured data on the `@cavuno/board` wire
|
|
@@ -107,18 +108,6 @@ declare function createAuthorProfileJsonLd({ author, canonical, description, ori
|
|
|
107
108
|
totalPosts: number;
|
|
108
109
|
}): JsonLdObject | null;
|
|
109
110
|
|
|
110
|
-
/**
|
|
111
|
-
* `BreadcrumbList` structured data, transcribed from the hosted board's
|
|
112
|
-
* `boards/_lib/server/breadcrumb-json-ld.ts` (`createBreadcrumbListJsonLd`)
|
|
113
|
-
* and golden-tested against it in-monorepo (ADR-0057).
|
|
114
|
-
*
|
|
115
|
-
* The hosted builder resolves relative hrefs against the board's canonical
|
|
116
|
-
* origin (custom domain aware, db-backed); this transcription takes the
|
|
117
|
-
* origin as a plain argument instead — pass absolute hrefs, or provide
|
|
118
|
-
* `options.origin` for relative ones. JSON-LD structure is locale-neutral:
|
|
119
|
-
* the labels are caller copy passed through.
|
|
120
|
-
*/
|
|
121
|
-
|
|
122
111
|
interface BreadcrumbItemInput {
|
|
123
112
|
label: string | null | undefined;
|
|
124
113
|
href?: string | null;
|
|
@@ -140,8 +129,12 @@ declare function createBreadcrumbJsonLd(items: BreadcrumbItemInput[], options?:
|
|
|
140
129
|
* (`/jobs/locations/:place/:category`), else `/jobs/:category`. The last
|
|
141
130
|
* crumb (the job title) carries no `path` — the current page. Mirrors
|
|
142
131
|
* page.tsx:336-367.
|
|
132
|
+
*
|
|
133
|
+
* The Home/Jobs crumb names resolve from the copy catalog per board
|
|
134
|
+
* language ⊕ operator overrides (ADR-0059); omitting `language` keeps the
|
|
135
|
+
* English source, so existing call sites render unchanged.
|
|
143
136
|
*/
|
|
144
|
-
declare function buildJobBreadcrumbs(job: PublicJob): Array<{
|
|
137
|
+
declare function buildJobBreadcrumbs(job: PublicJob, language?: string, labels?: BoardLabelOverrides): Array<{
|
|
145
138
|
name: string;
|
|
146
139
|
path?: string;
|
|
147
140
|
}>;
|
package/dist/seo.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { P as PublicBlogPostSummary, B as BlogAuthorEmbed, C as CompanyCategorySalary, a as CompanySalary, L as LocationSalaryDetail, S as SkillSalaryDetail, T as TitleSalaryDetail } from './salaries-
|
|
2
|
-
import { P as PublicBoard } from './board
|
|
3
|
-
import { P as PublicJob } from './jobs-
|
|
1
|
+
import { P as PublicBlogPostSummary, B as BlogAuthorEmbed, C as CompanyCategorySalary, a as CompanySalary, L as LocationSalaryDetail, S as SkillSalaryDetail, T as TitleSalaryDetail } from './salaries-B-zJKjkk.js';
|
|
2
|
+
import { P as PublicBoard } from './board-0yI5ZRJw.js';
|
|
3
|
+
import { P as PublicJob } from './jobs-Di4AV-02.js';
|
|
4
|
+
import { B as BoardLabelOverrides } from './ui-copy-rlfoH9P3.js';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Google for Jobs `JobPosting` structured data on the `@cavuno/board` wire
|
|
@@ -107,18 +108,6 @@ declare function createAuthorProfileJsonLd({ author, canonical, description, ori
|
|
|
107
108
|
totalPosts: number;
|
|
108
109
|
}): JsonLdObject | null;
|
|
109
110
|
|
|
110
|
-
/**
|
|
111
|
-
* `BreadcrumbList` structured data, transcribed from the hosted board's
|
|
112
|
-
* `boards/_lib/server/breadcrumb-json-ld.ts` (`createBreadcrumbListJsonLd`)
|
|
113
|
-
* and golden-tested against it in-monorepo (ADR-0057).
|
|
114
|
-
*
|
|
115
|
-
* The hosted builder resolves relative hrefs against the board's canonical
|
|
116
|
-
* origin (custom domain aware, db-backed); this transcription takes the
|
|
117
|
-
* origin as a plain argument instead — pass absolute hrefs, or provide
|
|
118
|
-
* `options.origin` for relative ones. JSON-LD structure is locale-neutral:
|
|
119
|
-
* the labels are caller copy passed through.
|
|
120
|
-
*/
|
|
121
|
-
|
|
122
111
|
interface BreadcrumbItemInput {
|
|
123
112
|
label: string | null | undefined;
|
|
124
113
|
href?: string | null;
|
|
@@ -140,8 +129,12 @@ declare function createBreadcrumbJsonLd(items: BreadcrumbItemInput[], options?:
|
|
|
140
129
|
* (`/jobs/locations/:place/:category`), else `/jobs/:category`. The last
|
|
141
130
|
* crumb (the job title) carries no `path` — the current page. Mirrors
|
|
142
131
|
* page.tsx:336-367.
|
|
132
|
+
*
|
|
133
|
+
* The Home/Jobs crumb names resolve from the copy catalog per board
|
|
134
|
+
* language ⊕ operator overrides (ADR-0059); omitting `language` keeps the
|
|
135
|
+
* English source, so existing call sites render unchanged.
|
|
143
136
|
*/
|
|
144
|
-
declare function buildJobBreadcrumbs(job: PublicJob): Array<{
|
|
137
|
+
declare function buildJobBreadcrumbs(job: PublicJob, language?: string, labels?: BoardLabelOverrides): Array<{
|
|
145
138
|
name: string;
|
|
146
139
|
path?: string;
|
|
147
140
|
}>;
|
package/dist/seo.js
CHANGED
|
@@ -161,6 +161,495 @@ function buildAbsoluteUrl(origin, path) {
|
|
|
161
161
|
}
|
|
162
162
|
}
|
|
163
163
|
|
|
164
|
+
// src/format/ui-copy.ts
|
|
165
|
+
var EN = {
|
|
166
|
+
jobCard: {
|
|
167
|
+
featuredLabel: "Featured",
|
|
168
|
+
aiRankedLabel: "AI-ranked",
|
|
169
|
+
sortNewestLabel: "Most recent",
|
|
170
|
+
sortSalaryHighLabel: "Salary: high to low"
|
|
171
|
+
},
|
|
172
|
+
jobSearch: {
|
|
173
|
+
headingJobs: "Jobs",
|
|
174
|
+
keywordLabel: "Keyword",
|
|
175
|
+
keywordPlaceholder: "Search jobs\u2026",
|
|
176
|
+
locationLabel: "Location",
|
|
177
|
+
locationPlaceholder: "City or region",
|
|
178
|
+
workplacePlaceholder: "Workplace",
|
|
179
|
+
anyWorkplaceLabel: "Any workplace",
|
|
180
|
+
typePlaceholder: "Type",
|
|
181
|
+
anyTypeLabel: "Any type",
|
|
182
|
+
sortPlaceholder: "Sort",
|
|
183
|
+
loadMoreLabel: "Load more",
|
|
184
|
+
noJobsMatchText: "No jobs match \u2014 try clearing a filter."
|
|
185
|
+
},
|
|
186
|
+
jobDetail: {
|
|
187
|
+
categoriesHeading: "Categories",
|
|
188
|
+
skillsHeading: "Skills",
|
|
189
|
+
additionalDetailsHeading: "Additional details",
|
|
190
|
+
customFieldYesLabel: "Yes",
|
|
191
|
+
customFieldNoLabel: "No",
|
|
192
|
+
locationsLabel: "Locations",
|
|
193
|
+
workPermitsLabel: "Work permits",
|
|
194
|
+
timezonesLabel: "Timezones",
|
|
195
|
+
educationLabel: "Education",
|
|
196
|
+
experienceLabel: "Experience",
|
|
197
|
+
worldwideLabel: "Worldwide",
|
|
198
|
+
noExperienceRequiredLabel: "No experience required",
|
|
199
|
+
experienceYears: (years) => `${years}+ years`,
|
|
200
|
+
posted: (published) => `Posted ${published}`,
|
|
201
|
+
noDescriptionText: "No description provided.",
|
|
202
|
+
viewCompanyProfileLabel: "View company profile",
|
|
203
|
+
similarJobsHeading: "Similar jobs",
|
|
204
|
+
breadcrumbAriaLabel: "Breadcrumb"
|
|
205
|
+
},
|
|
206
|
+
apply: {
|
|
207
|
+
applyButtonText: "Apply for this job",
|
|
208
|
+
applyingLabel: "Applying\u2026",
|
|
209
|
+
applyOnEmployerSiteLabel: "Apply on employer site",
|
|
210
|
+
signInToApplyLabel: "Sign in to apply",
|
|
211
|
+
verifyEmailToApplyLabel: "Verify email to apply",
|
|
212
|
+
appliedViewApplicationsLabel: "Applied \u2014 view applications",
|
|
213
|
+
applicationSubmitError: "Something went wrong. Please try again."
|
|
214
|
+
},
|
|
215
|
+
alerts: {
|
|
216
|
+
jobAlertTitle: "Get job alerts",
|
|
217
|
+
jobAlertEmailPlaceholder: "you@example.com",
|
|
218
|
+
jobAlertButtonText: "Get alerts",
|
|
219
|
+
subscribingLabel: "Subscribing\u2026",
|
|
220
|
+
jobAlertSuccessToast: "Check your email to confirm your subscription.",
|
|
221
|
+
jobAlertDuplicateToast: "You're already subscribed to this alert.",
|
|
222
|
+
jobAlertErrorToast: "Something went wrong. Please try again.",
|
|
223
|
+
sectionAriaLabel: "Job alerts",
|
|
224
|
+
emailAriaLabel: "email",
|
|
225
|
+
submitAriaLabel: "get job alerts"
|
|
226
|
+
},
|
|
227
|
+
copyLink: {
|
|
228
|
+
copyLinkLabel: "Copy link",
|
|
229
|
+
copiedLabel: "Copied",
|
|
230
|
+
ariaLabel: "copy link"
|
|
231
|
+
},
|
|
232
|
+
salary: {
|
|
233
|
+
comparisonHeadlineAverage: "Average salary",
|
|
234
|
+
perYearSuffix: "/ year",
|
|
235
|
+
comparisonPercentile25Label: "25th percentile",
|
|
236
|
+
medianLabel: "Median",
|
|
237
|
+
comparisonPercentile75Label: "75th percentile",
|
|
238
|
+
basedOnLabel: "Based on",
|
|
239
|
+
seniorityTableHeaderLevel: "Level",
|
|
240
|
+
seniorityTableHeaderAvg: "Average",
|
|
241
|
+
boardBaselineLabel: "Board baseline",
|
|
242
|
+
seniorityTableHeaderDiff: "vs. board",
|
|
243
|
+
faqHeading: "Frequently asked questions"
|
|
244
|
+
},
|
|
245
|
+
nav: {
|
|
246
|
+
home: "Jobs",
|
|
247
|
+
companies: "Companies",
|
|
248
|
+
pricing: "Pricing",
|
|
249
|
+
talent: "Talent",
|
|
250
|
+
post: "Post a job",
|
|
251
|
+
blog: "Blog"
|
|
252
|
+
},
|
|
253
|
+
footer: {
|
|
254
|
+
forCandidatesHeading: "For Candidates",
|
|
255
|
+
forCompaniesHeading: "For Companies",
|
|
256
|
+
resourcesHeading: "Resources",
|
|
257
|
+
aboutHeading: "About",
|
|
258
|
+
websiteLabel: "Website",
|
|
259
|
+
aboutLabel: "About",
|
|
260
|
+
contactLabel: "Contact us",
|
|
261
|
+
locationsLabel: "Locations",
|
|
262
|
+
salariesLabel: "Salaries",
|
|
263
|
+
sitemapLabel: "Sitemap",
|
|
264
|
+
termsOfServiceLabel: "Terms of Service",
|
|
265
|
+
privacyPolicyLabel: "Privacy Policy",
|
|
266
|
+
cookiePolicyLabel: "Cookie Policy",
|
|
267
|
+
impressumLabel: "Impressum",
|
|
268
|
+
allRightsReservedText: "All rights reserved.",
|
|
269
|
+
copyrightPrefix: "\xA9 {{year}} {{board_name}}.",
|
|
270
|
+
poweredByText: "Powered by",
|
|
271
|
+
defaultDescription: "Discover the latest roles from {{board_name}}."
|
|
272
|
+
},
|
|
273
|
+
breadcrumbs: {
|
|
274
|
+
home: "Home",
|
|
275
|
+
jobs: "Jobs",
|
|
276
|
+
locations: "Locations",
|
|
277
|
+
salaries: "Salaries",
|
|
278
|
+
companies: "Companies",
|
|
279
|
+
skills: "Skills",
|
|
280
|
+
titles: "Titles",
|
|
281
|
+
blog: "Blog",
|
|
282
|
+
post: "Post a Job",
|
|
283
|
+
pricing: "Pricing",
|
|
284
|
+
about: "About",
|
|
285
|
+
impressum: "Impressum",
|
|
286
|
+
termsOfService: "Terms of Service",
|
|
287
|
+
privacyPolicy: "Privacy Policy",
|
|
288
|
+
cookiePolicy: "Cookie Policy",
|
|
289
|
+
talent: "Talent"
|
|
290
|
+
},
|
|
291
|
+
pagination: {
|
|
292
|
+
ariaLabel: "Pagination",
|
|
293
|
+
previousLabel: "Previous",
|
|
294
|
+
nextLabel: "Next"
|
|
295
|
+
},
|
|
296
|
+
blog: {
|
|
297
|
+
bylineLabel: "By",
|
|
298
|
+
readingTimeLabel: "min read",
|
|
299
|
+
searchLabel: "Search",
|
|
300
|
+
searchPlaceholder: "Search posts...",
|
|
301
|
+
clearButtonLabel: "Clear search",
|
|
302
|
+
tagFilterLabel: "Topics",
|
|
303
|
+
tagFilterAllLabel: "All",
|
|
304
|
+
emptyTitle: "No matching posts",
|
|
305
|
+
emptyDescription: "Try adjusting your search or clearing your filters.",
|
|
306
|
+
emptyResetLabel: "Clear filters"
|
|
307
|
+
},
|
|
308
|
+
entity: {
|
|
309
|
+
jobSingular: "job",
|
|
310
|
+
jobPlural: "jobs",
|
|
311
|
+
companySingular: "company",
|
|
312
|
+
companyPlural: "companies"
|
|
313
|
+
}
|
|
314
|
+
};
|
|
315
|
+
var DE = {
|
|
316
|
+
jobCard: {
|
|
317
|
+
featuredLabel: "Hervorgehoben",
|
|
318
|
+
aiRankedLabel: "KI-sortiert",
|
|
319
|
+
sortNewestLabel: "Neueste zuerst",
|
|
320
|
+
sortSalaryHighLabel: "Gehalt: absteigend"
|
|
321
|
+
},
|
|
322
|
+
jobSearch: {
|
|
323
|
+
headingJobs: "Jobs",
|
|
324
|
+
keywordLabel: "Stichwort",
|
|
325
|
+
keywordPlaceholder: "Jobtitel oder -beschreibungen suchen",
|
|
326
|
+
locationLabel: "Standort",
|
|
327
|
+
locationPlaceholder: "Stadt, Land oder Region",
|
|
328
|
+
workplacePlaceholder: "Arbeitsmodell",
|
|
329
|
+
anyWorkplaceLabel: "Alle Arbeitsmodelle",
|
|
330
|
+
typePlaceholder: "Anstellungsart",
|
|
331
|
+
anyTypeLabel: "Alle Anstellungsarten",
|
|
332
|
+
sortPlaceholder: "Sortieren",
|
|
333
|
+
loadMoreLabel: "Mehr laden",
|
|
334
|
+
noJobsMatchText: "Keine passenden Jobs \u2014 setze einen Filter zur\xFCck."
|
|
335
|
+
},
|
|
336
|
+
jobDetail: {
|
|
337
|
+
categoriesHeading: "Kategorien",
|
|
338
|
+
skillsHeading: "F\xE4higkeiten",
|
|
339
|
+
additionalDetailsHeading: "Weitere Details",
|
|
340
|
+
customFieldYesLabel: "Ja",
|
|
341
|
+
customFieldNoLabel: "Nein",
|
|
342
|
+
locationsLabel: "Standorte",
|
|
343
|
+
workPermitsLabel: "Arbeitserlaubnis",
|
|
344
|
+
timezonesLabel: "Zeitzonen",
|
|
345
|
+
educationLabel: "Ausbildung",
|
|
346
|
+
experienceLabel: "Berufserfahrung",
|
|
347
|
+
worldwideLabel: "Weltweit",
|
|
348
|
+
noExperienceRequiredLabel: "Keine Berufserfahrung erforderlich",
|
|
349
|
+
experienceYears: (years) => `${years}+ Jahre`,
|
|
350
|
+
posted: (published) => `Ver\xF6ffentlicht ${published}`,
|
|
351
|
+
noDescriptionText: "Keine Beschreibung vorhanden.",
|
|
352
|
+
viewCompanyProfileLabel: "Unternehmensprofil ansehen",
|
|
353
|
+
similarJobsHeading: "\xC4hnliche Jobs",
|
|
354
|
+
breadcrumbAriaLabel: "Seitenpfad"
|
|
355
|
+
},
|
|
356
|
+
apply: {
|
|
357
|
+
applyButtonText: "Jetzt bewerben",
|
|
358
|
+
applyingLabel: "Wird gesendet \u2026",
|
|
359
|
+
applyOnEmployerSiteLabel: "Beim Unternehmen bewerben",
|
|
360
|
+
signInToApplyLabel: "Zum Bewerben anmelden",
|
|
361
|
+
verifyEmailToApplyLabel: "E-Mail best\xE4tigen, um dich zu bewerben",
|
|
362
|
+
appliedViewApplicationsLabel: "Beworben \u2014 Bewerbungen ansehen",
|
|
363
|
+
applicationSubmitError: "Etwas ist schiefgelaufen. Bitte versuche es erneut."
|
|
364
|
+
},
|
|
365
|
+
alerts: {
|
|
366
|
+
jobAlertTitle: "Job-Benachrichtigungen erhalten",
|
|
367
|
+
jobAlertEmailPlaceholder: "name@beispiel.de",
|
|
368
|
+
jobAlertButtonText: "Abonnieren",
|
|
369
|
+
subscribingLabel: "Wird abonniert \u2026",
|
|
370
|
+
jobAlertSuccessToast: "\xDCberpr\xFCfe deine E-Mails, um dein Abonnement zu best\xE4tigen.",
|
|
371
|
+
jobAlertDuplicateToast: "Du hast diese Benachrichtigung bereits abonniert.",
|
|
372
|
+
jobAlertErrorToast: "Etwas ist schiefgelaufen. Bitte versuche es erneut.",
|
|
373
|
+
sectionAriaLabel: "Job-Benachrichtigungen",
|
|
374
|
+
emailAriaLabel: "E-Mail",
|
|
375
|
+
submitAriaLabel: "Job-Benachrichtigungen erhalten"
|
|
376
|
+
},
|
|
377
|
+
copyLink: {
|
|
378
|
+
copyLinkLabel: "Link kopieren",
|
|
379
|
+
copiedLabel: "Kopiert",
|
|
380
|
+
ariaLabel: "Link kopieren"
|
|
381
|
+
},
|
|
382
|
+
salary: {
|
|
383
|
+
comparisonHeadlineAverage: "Durchschnittsgehalt",
|
|
384
|
+
perYearSuffix: "/ Jahr",
|
|
385
|
+
comparisonPercentile25Label: "25. Perzentil",
|
|
386
|
+
medianLabel: "Median",
|
|
387
|
+
comparisonPercentile75Label: "75. Perzentil",
|
|
388
|
+
basedOnLabel: "Basierend auf",
|
|
389
|
+
seniorityTableHeaderLevel: "Erfahrungslevel",
|
|
390
|
+
seniorityTableHeaderAvg: "Durchschnitt",
|
|
391
|
+
boardBaselineLabel: "Board-Durchschnitt",
|
|
392
|
+
seniorityTableHeaderDiff: "vs. Board",
|
|
393
|
+
faqHeading: "H\xE4ufig gestellte Fragen"
|
|
394
|
+
},
|
|
395
|
+
nav: {
|
|
396
|
+
home: "Jobs",
|
|
397
|
+
companies: "Unternehmen",
|
|
398
|
+
pricing: "Preise",
|
|
399
|
+
talent: "Talente",
|
|
400
|
+
post: "Job ver\xF6ffentlichen",
|
|
401
|
+
blog: "Blog"
|
|
402
|
+
},
|
|
403
|
+
footer: {
|
|
404
|
+
forCandidatesHeading: "F\xFCr Kandidaten",
|
|
405
|
+
forCompaniesHeading: "F\xFCr Unternehmen",
|
|
406
|
+
resourcesHeading: "Ressourcen",
|
|
407
|
+
aboutHeading: "\xDCber uns",
|
|
408
|
+
websiteLabel: "Website",
|
|
409
|
+
aboutLabel: "\xDCber uns",
|
|
410
|
+
contactLabel: "Kontakt",
|
|
411
|
+
locationsLabel: "Standorte",
|
|
412
|
+
salariesLabel: "Geh\xE4lter",
|
|
413
|
+
sitemapLabel: "Sitemap",
|
|
414
|
+
termsOfServiceLabel: "Nutzungsbedingungen",
|
|
415
|
+
privacyPolicyLabel: "Datenschutzerkl\xE4rung",
|
|
416
|
+
cookiePolicyLabel: "Cookie-Richtlinie",
|
|
417
|
+
impressumLabel: "Impressum",
|
|
418
|
+
allRightsReservedText: "Alle Rechte vorbehalten.",
|
|
419
|
+
copyrightPrefix: "\xA9 {{year}} {{board_name}}.",
|
|
420
|
+
poweredByText: "Bereitgestellt von",
|
|
421
|
+
defaultDescription: "Entdecke die neuesten Stellen von {{board_name}}."
|
|
422
|
+
},
|
|
423
|
+
breadcrumbs: {
|
|
424
|
+
home: "Startseite",
|
|
425
|
+
jobs: "Jobs",
|
|
426
|
+
locations: "Standorte",
|
|
427
|
+
salaries: "Geh\xE4lter",
|
|
428
|
+
companies: "Unternehmen",
|
|
429
|
+
skills: "F\xE4higkeiten",
|
|
430
|
+
titles: "Berufsbezeichnungen",
|
|
431
|
+
blog: "Blog",
|
|
432
|
+
post: "Job ver\xF6ffentlichen",
|
|
433
|
+
pricing: "Preise",
|
|
434
|
+
about: "\xDCber uns",
|
|
435
|
+
impressum: "Impressum",
|
|
436
|
+
termsOfService: "Nutzungsbedingungen",
|
|
437
|
+
privacyPolicy: "Datenschutzerkl\xE4rung",
|
|
438
|
+
cookiePolicy: "Cookie-Richtlinie",
|
|
439
|
+
talent: "Talente"
|
|
440
|
+
},
|
|
441
|
+
pagination: {
|
|
442
|
+
ariaLabel: "Seitennummerierung",
|
|
443
|
+
previousLabel: "Zur\xFCck",
|
|
444
|
+
nextLabel: "Weiter"
|
|
445
|
+
},
|
|
446
|
+
blog: {
|
|
447
|
+
bylineLabel: "Von",
|
|
448
|
+
readingTimeLabel: "Minuten Lesezeit",
|
|
449
|
+
searchLabel: "Suche",
|
|
450
|
+
searchPlaceholder: "Artikel suchen...",
|
|
451
|
+
clearButtonLabel: "Suche leeren",
|
|
452
|
+
tagFilterLabel: "Themen",
|
|
453
|
+
tagFilterAllLabel: "Alle",
|
|
454
|
+
emptyTitle: "Keine passenden Artikel gefunden",
|
|
455
|
+
emptyDescription: "Versuche, deine Suche anzupassen oder die Filter zur\xFCckzusetzen.",
|
|
456
|
+
emptyResetLabel: "Filter zur\xFCcksetzen"
|
|
457
|
+
},
|
|
458
|
+
entity: {
|
|
459
|
+
jobSingular: "Job",
|
|
460
|
+
jobPlural: "Jobs",
|
|
461
|
+
companySingular: "Unternehmen",
|
|
462
|
+
companyPlural: "Unternehmen"
|
|
463
|
+
}
|
|
464
|
+
};
|
|
465
|
+
var FR = {
|
|
466
|
+
jobCard: {
|
|
467
|
+
featuredLabel: "\xC0 la une",
|
|
468
|
+
aiRankedLabel: "Classement IA",
|
|
469
|
+
sortNewestLabel: "Plus r\xE9centes",
|
|
470
|
+
sortSalaryHighLabel: "Salaire : d\xE9croissant"
|
|
471
|
+
},
|
|
472
|
+
jobSearch: {
|
|
473
|
+
headingJobs: "Offres d'emploi",
|
|
474
|
+
keywordLabel: "Mot-cl\xE9",
|
|
475
|
+
keywordPlaceholder: "Rechercher une offre\u2026",
|
|
476
|
+
locationLabel: "Lieu",
|
|
477
|
+
locationPlaceholder: "Ville ou r\xE9gion",
|
|
478
|
+
workplacePlaceholder: "Mode de travail",
|
|
479
|
+
anyWorkplaceLabel: "Tous les modes de travail",
|
|
480
|
+
typePlaceholder: "Type de contrat",
|
|
481
|
+
anyTypeLabel: "Tous les types",
|
|
482
|
+
sortPlaceholder: "Trier",
|
|
483
|
+
loadMoreLabel: "Voir plus",
|
|
484
|
+
noJobsMatchText: "Aucune offre ne correspond \u2014 essayez de retirer un filtre."
|
|
485
|
+
},
|
|
486
|
+
jobDetail: {
|
|
487
|
+
categoriesHeading: "Cat\xE9gories",
|
|
488
|
+
skillsHeading: "Comp\xE9tences",
|
|
489
|
+
additionalDetailsHeading: "Informations compl\xE9mentaires",
|
|
490
|
+
customFieldYesLabel: "Oui",
|
|
491
|
+
customFieldNoLabel: "Non",
|
|
492
|
+
locationsLabel: "Lieux",
|
|
493
|
+
workPermitsLabel: "Permis de travail",
|
|
494
|
+
timezonesLabel: "Fuseaux horaires",
|
|
495
|
+
educationLabel: "Formation",
|
|
496
|
+
experienceLabel: "Exp\xE9rience",
|
|
497
|
+
worldwideLabel: "Monde entier",
|
|
498
|
+
noExperienceRequiredLabel: "Aucune exp\xE9rience requise",
|
|
499
|
+
experienceYears: (years) => `${years}+ ans`,
|
|
500
|
+
posted: (published) => `Publi\xE9e ${published}`,
|
|
501
|
+
noDescriptionText: "Aucune description fournie.",
|
|
502
|
+
viewCompanyProfileLabel: "Voir le profil de l'entreprise",
|
|
503
|
+
similarJobsHeading: "Offres similaires",
|
|
504
|
+
breadcrumbAriaLabel: "Fil d'Ariane"
|
|
505
|
+
},
|
|
506
|
+
apply: {
|
|
507
|
+
applyButtonText: "Postuler \xE0 cette offre",
|
|
508
|
+
applyingLabel: "Envoi en cours\u2026",
|
|
509
|
+
applyOnEmployerSiteLabel: "Postuler sur le site de l'employeur",
|
|
510
|
+
signInToApplyLabel: "Connectez-vous pour postuler",
|
|
511
|
+
verifyEmailToApplyLabel: "V\xE9rifiez votre e-mail pour postuler",
|
|
512
|
+
appliedViewApplicationsLabel: "Candidature envoy\xE9e \u2014 voir mes candidatures",
|
|
513
|
+
applicationSubmitError: "Une erreur est survenue. Veuillez r\xE9essayer."
|
|
514
|
+
},
|
|
515
|
+
alerts: {
|
|
516
|
+
jobAlertTitle: "Recevoir des alertes emploi",
|
|
517
|
+
jobAlertEmailPlaceholder: "vous@exemple.fr",
|
|
518
|
+
jobAlertButtonText: "Activer les alertes",
|
|
519
|
+
subscribingLabel: "Abonnement en cours\u2026",
|
|
520
|
+
jobAlertSuccessToast: "V\xE9rifiez votre e-mail pour confirmer votre abonnement.",
|
|
521
|
+
jobAlertDuplicateToast: "Vous \xEAtes d\xE9j\xE0 abonn\xE9 \xE0 cette alerte.",
|
|
522
|
+
jobAlertErrorToast: "Une erreur est survenue. Veuillez r\xE9essayer.",
|
|
523
|
+
sectionAriaLabel: "Alertes emploi",
|
|
524
|
+
emailAriaLabel: "e-mail",
|
|
525
|
+
submitAriaLabel: "recevoir des alertes emploi"
|
|
526
|
+
},
|
|
527
|
+
copyLink: {
|
|
528
|
+
copyLinkLabel: "Copier le lien",
|
|
529
|
+
copiedLabel: "Copi\xE9",
|
|
530
|
+
ariaLabel: "copier le lien"
|
|
531
|
+
},
|
|
532
|
+
salary: {
|
|
533
|
+
comparisonHeadlineAverage: "Salaire moyen",
|
|
534
|
+
perYearSuffix: "/ an",
|
|
535
|
+
comparisonPercentile25Label: "25e percentile",
|
|
536
|
+
medianLabel: "M\xE9diane",
|
|
537
|
+
comparisonPercentile75Label: "75e percentile",
|
|
538
|
+
basedOnLabel: "Bas\xE9 sur",
|
|
539
|
+
seniorityTableHeaderLevel: "Niveau",
|
|
540
|
+
seniorityTableHeaderAvg: "Moyenne",
|
|
541
|
+
boardBaselineLabel: "R\xE9f\xE9rence du site",
|
|
542
|
+
seniorityTableHeaderDiff: "vs site",
|
|
543
|
+
faqHeading: "Questions fr\xE9quentes"
|
|
544
|
+
},
|
|
545
|
+
nav: {
|
|
546
|
+
home: "Offres",
|
|
547
|
+
companies: "Entreprises",
|
|
548
|
+
pricing: "Tarifs",
|
|
549
|
+
talent: "Talents",
|
|
550
|
+
post: "Publier une offre",
|
|
551
|
+
blog: "Blog"
|
|
552
|
+
},
|
|
553
|
+
footer: {
|
|
554
|
+
forCandidatesHeading: "Pour les candidats",
|
|
555
|
+
forCompaniesHeading: "Pour les entreprises",
|
|
556
|
+
resourcesHeading: "Ressources",
|
|
557
|
+
aboutHeading: "\xC0 propos",
|
|
558
|
+
websiteLabel: "Site web",
|
|
559
|
+
aboutLabel: "\xC0 propos",
|
|
560
|
+
contactLabel: "Nous contacter",
|
|
561
|
+
locationsLabel: "Lieux",
|
|
562
|
+
salariesLabel: "Salaires",
|
|
563
|
+
sitemapLabel: "Plan du site",
|
|
564
|
+
termsOfServiceLabel: "Conditions d'utilisation",
|
|
565
|
+
privacyPolicyLabel: "Politique de confidentialit\xE9",
|
|
566
|
+
cookiePolicyLabel: "Politique de cookies",
|
|
567
|
+
impressumLabel: "Mentions l\xE9gales",
|
|
568
|
+
allRightsReservedText: "Tous droits r\xE9serv\xE9s.",
|
|
569
|
+
copyrightPrefix: "\xA9 {{year}} {{board_name}}.",
|
|
570
|
+
poweredByText: "Propuls\xE9 par",
|
|
571
|
+
defaultDescription: "D\xE9couvrez les derni\xE8res offres de {{board_name}}."
|
|
572
|
+
},
|
|
573
|
+
breadcrumbs: {
|
|
574
|
+
home: "Accueil",
|
|
575
|
+
jobs: "Offres",
|
|
576
|
+
locations: "Lieux",
|
|
577
|
+
salaries: "Salaires",
|
|
578
|
+
companies: "Entreprises",
|
|
579
|
+
skills: "Comp\xE9tences",
|
|
580
|
+
titles: "Intitul\xE9s de poste",
|
|
581
|
+
blog: "Blog",
|
|
582
|
+
post: "Publier une offre",
|
|
583
|
+
pricing: "Tarifs",
|
|
584
|
+
about: "\xC0 propos",
|
|
585
|
+
impressum: "Mentions l\xE9gales",
|
|
586
|
+
termsOfService: "Conditions d'utilisation",
|
|
587
|
+
privacyPolicy: "Politique de confidentialit\xE9",
|
|
588
|
+
cookiePolicy: "Politique de cookies",
|
|
589
|
+
talent: "Talents"
|
|
590
|
+
},
|
|
591
|
+
pagination: {
|
|
592
|
+
ariaLabel: "Pagination",
|
|
593
|
+
previousLabel: "Pr\xE9c\xE9dent",
|
|
594
|
+
nextLabel: "Suivant"
|
|
595
|
+
},
|
|
596
|
+
blog: {
|
|
597
|
+
bylineLabel: "Par",
|
|
598
|
+
readingTimeLabel: "min de lecture",
|
|
599
|
+
searchLabel: "Recherche",
|
|
600
|
+
searchPlaceholder: "Rechercher un article...",
|
|
601
|
+
clearButtonLabel: "Effacer la recherche",
|
|
602
|
+
tagFilterLabel: "Th\xE8mes",
|
|
603
|
+
tagFilterAllLabel: "Tous",
|
|
604
|
+
emptyTitle: "Aucun article correspondant",
|
|
605
|
+
emptyDescription: "Essayez de modifier votre recherche ou de r\xE9initialiser les filtres.",
|
|
606
|
+
emptyResetLabel: "R\xE9initialiser les filtres"
|
|
607
|
+
},
|
|
608
|
+
entity: {
|
|
609
|
+
jobSingular: "offre",
|
|
610
|
+
jobPlural: "offres",
|
|
611
|
+
companySingular: "entreprise",
|
|
612
|
+
companyPlural: "entreprises"
|
|
613
|
+
}
|
|
614
|
+
};
|
|
615
|
+
var CATALOGS = { en: EN, de: DE, fr: FR };
|
|
616
|
+
function mergeGroup(group, overrides) {
|
|
617
|
+
if (!overrides) return group;
|
|
618
|
+
const out = { ...group };
|
|
619
|
+
for (const [key, value] of Object.entries(group)) {
|
|
620
|
+
if (typeof value !== "string") continue;
|
|
621
|
+
const override = overrides[key];
|
|
622
|
+
if (typeof override === "string" && override.trim() !== "") {
|
|
623
|
+
out[key] = override;
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
return out;
|
|
627
|
+
}
|
|
628
|
+
var GROUP_OVERRIDE_SOURCE = {
|
|
629
|
+
jobCard: "jobCardLabels",
|
|
630
|
+
jobSearch: "jobSearchLabels",
|
|
631
|
+
jobDetail: "jobCardLabels",
|
|
632
|
+
apply: "jobCardLabels",
|
|
633
|
+
alerts: "jobCardLabels",
|
|
634
|
+
copyLink: "jobCardLabels",
|
|
635
|
+
salary: "salaryLabels",
|
|
636
|
+
nav: "navLabels",
|
|
637
|
+
footer: "footerLabels",
|
|
638
|
+
breadcrumbs: "breadcrumbsLabels",
|
|
639
|
+
pagination: "globalPaginationLabels",
|
|
640
|
+
blog: "blogSharedLabels",
|
|
641
|
+
entity: "entityLabels"
|
|
642
|
+
};
|
|
643
|
+
function uiCopy(language, labels) {
|
|
644
|
+
const catalog = language && CATALOGS[language] || EN;
|
|
645
|
+
if (!labels) return catalog;
|
|
646
|
+
const resolved = {};
|
|
647
|
+
for (const [group, source] of Object.entries(GROUP_OVERRIDE_SOURCE)) {
|
|
648
|
+
resolved[group] = mergeGroup(catalog[group], labels[source]);
|
|
649
|
+
}
|
|
650
|
+
return resolved;
|
|
651
|
+
}
|
|
652
|
+
|
|
164
653
|
// src/seo/breadcrumbs.ts
|
|
165
654
|
function createBreadcrumbJsonLd(items, options = {}) {
|
|
166
655
|
const normalizedItems = items.map((item) => {
|
|
@@ -204,10 +693,11 @@ function resolveBreadcrumbHref(href, origin) {
|
|
|
204
693
|
function isAbsoluteUrl(href) {
|
|
205
694
|
return /^https?:\/\//i.test(href);
|
|
206
695
|
}
|
|
207
|
-
function buildJobBreadcrumbs(job) {
|
|
696
|
+
function buildJobBreadcrumbs(job, language, labels) {
|
|
697
|
+
const copy = uiCopy(language, labels).breadcrumbs;
|
|
208
698
|
const crumbs = [
|
|
209
|
-
{ name:
|
|
210
|
-
{ name:
|
|
699
|
+
{ name: copy.home, path: "/" },
|
|
700
|
+
{ name: copy.jobs, path: "/jobs" }
|
|
211
701
|
];
|
|
212
702
|
let lastPlaceSlug = null;
|
|
213
703
|
for (const place of job.placeHierarchy) {
|
|
@@ -727,7 +1217,7 @@ function listingJsonLd(options) {
|
|
|
727
1217
|
}
|
|
728
1218
|
|
|
729
1219
|
// src/format/salary-lexicon.ts
|
|
730
|
-
var
|
|
1220
|
+
var EN2 = {
|
|
731
1221
|
timeframe: {
|
|
732
1222
|
per_year: "Yearly",
|
|
733
1223
|
per_month: "Monthly",
|
|
@@ -771,7 +1261,7 @@ var EN = {
|
|
|
771
1261
|
categorySalaryDataFor: ({ category, company, board }) => `${category} salary data for ${company} on ${board}.`
|
|
772
1262
|
}
|
|
773
1263
|
};
|
|
774
|
-
var
|
|
1264
|
+
var DE2 = {
|
|
775
1265
|
timeframe: {
|
|
776
1266
|
per_year: "pro Jahr",
|
|
777
1267
|
per_month: "pro Monat",
|
|
@@ -815,9 +1305,9 @@ var DE = {
|
|
|
815
1305
|
categorySalaryDataFor: ({ category, company, board }) => `${category}-Gehaltsdaten f\xFCr ${company} auf ${board}.`
|
|
816
1306
|
}
|
|
817
1307
|
};
|
|
818
|
-
var LEXICONS = { en:
|
|
1308
|
+
var LEXICONS = { en: EN2, de: DE2 };
|
|
819
1309
|
function getSalaryLexicon(locale) {
|
|
820
|
-
return locale && LEXICONS[locale] ||
|
|
1310
|
+
return locale && LEXICONS[locale] || EN2;
|
|
821
1311
|
}
|
|
822
1312
|
|
|
823
1313
|
// src/seo/salary.ts
|