Skip to content

bug: competitionJsonLd() emits an Event-only eventAttendanceMode on scholarship records #256

Description

@yakew7

Problem

src/lib/jsonld.ts's schemaOrgCompetitionType() correctly types scholarship-category competitions as EducationalOccupationalProgram instead of Event (a scholarship judged on a body of work isn't a dated event):

export function schemaOrgCompetitionType(category: Competition["category"]): string {
  return category === "scholarship" ? "EducationalOccupationalProgram" : "Event";
}

But competitionJsonLd() unconditionally sets eventAttendanceMode on every competition regardless of its resolved @type:

const node: Record<string, unknown> = {
  "@context": "https://schema.org",
  "@type": schemaOrgCompetitionType(competition.category),
  // ...
  eventAttendanceMode: EVENT_ATTENDANCE_MODES[competition.format],
  isAccessibleForFree: competition.fee.amount === 0,
};

eventAttendanceMode is a schema.org Event-only property — it isn't a valid property of EducationalOccupationalProgram. So the JSON-LD emitted for the 5 records in data/competitions/scholarship.json (e.g. davidson-fellows-scholarship) declares "@type": "EducationalOccupationalProgram" while also carrying an Event-only field, which is exactly the kind of type/property mismatch Google's Rich Results structured-data validator flags.

Fix

In competitionJsonLd(), only include eventAttendanceMode (and startDate/endDate, which are also Event-shaped) when schemaOrgCompetitionType(competition.category) === "Event". For the scholarship branch, consider adding EducationalOccupationalProgram-appropriate properties instead (e.g. applicationDeadline from the record's dates[]) if useful, or simply omit the Event-only fields.

Acceptance criteria

  • eventAttendanceMode (and startDate/endDate) only appear on Event-typed JSON-LD nodes
  • A scholarship competition's rendered JSON-LD passes Google's Rich Results structured-data test with no type-mismatch warning
  • src/lib/jsonld.test.ts (or a new test) covers a scholarship-category competition

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingseoSearch and discoverability

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions