Competitor Card

A team or athlete profile card with season statistics, recent form, the next or last fixture with odds, and inline Fixtures, Squad and Season stats panels.

A competitor profile card — the competitor's identity, their season statistics with a competition switcher, recent form, the next or last fixture (with betting odds, or a live badge while it is in progress), and two inline panels opened from the header. data-content-id takes either kind of competitor and the card adapts: a team (fb:t:…) shows the club's season and opens a Squad panel; an athlete (fb:p:…) shows the player's season and opens a Season stats table, with the form and fixtures of their club.

📘

No authentication required — this widget never needs tokenString, tokenCookieName, or firebase in your config. See Getting Started → Authentication → Read-only widgets.

<div data-component="fu-widget" data-content-type="competitor-card" data-content-id="fb:t:8205"></div>

Configuration Attributes

AttributeDescriptionOptions/FormatDefault
data-content-idCompetitor ID — a team or an athletee.g. "fb:t:8205", "fb:p:48824"Required
data-competitor-card-templateLayout (see Templates below)"standard", "hero", "horizontal", "compact""standard"
data-competitor-card-show-countryPut the competitor's country in the header subtitle"true", "false"true
data-competitor-card-header-layoutCrest beside the name, or stacked above it with the header centred"horizontal", "stacked""stacked" on horizontal, else "horizontal"
data-competitor-card-cta-layoutWhere the header's two buttons sit. "responsive" stacks them in a narrow container"inline", "stacked", "responsive""responsive"
data-competitor-card-title-positionAlignment of every section title"left", "center", "right""left"
data-competitor-card-show-competition-switcherRender the All + one-per-competition switcher. Renders nothing with a single competition"true", "false"true
data-competitor-card-has-brandingPaint the branded surfaces with the competitor's own colours instead of the theme accent"true", "false"true
data-competitor-card-header-background-gradientCSS background for the branded header (hero and horizontal only)Any CSS backgroundCompetitor branding
data-competitor-card-live-refreshPoll while one of the competitor's fixtures is LIVE, so score and minute stay current"true", "false"true
data-competitor-card-refresh-intervalLive-refresh poll interval in millisecondsPositive integer30000 (30s)
data-competitor-card-labelsJSON object overriding any user-facing stringCompetitorCardLabels, e.g. '{"squad":"Players"}'Locale strings
data-competitor-card-add-to-betslipPush a clicked odds price into the Betslip widget on the page (see Betting Odds below)"true", "false"false

Section attributes:

AttributeDescriptionOptions/FormatDefault
data-competitor-card-show-statsRender the season-statistics section"true", "false"true
data-competitor-card-stats-background-gradientCSS background for the headline tile (the points tile on a team)Any CSS backgroundCompetitor branding
data-competitor-card-show-formRender the recent-form strip"true", "false"true
data-competitor-card-form-max-itemsHow many past fixtures to show, latest firstInteger, clamped to 3–105
data-competitor-card-show-featured-matchRender the featured next/last fixture"true", "false"true
data-competitor-card-featured-match-typeWhich fixture the section opens on. A live fixture always wins"next", "last""next"
data-competitor-card-featured-match-toggleShow the Last | Next toggle"true", "false"true
data-competitor-card-featured-match-background-gradientCSS background for the featured-match panelAny CSS backgroundSoft wash of the competitor branding
data-competitor-card-show-oddsRender outright odds under an upcoming featured match"true", "false"true
data-competitor-card-odds-mode"flash" alternates the operator logo and the prices instead of showing both"default", "flash""flash" on compact, else "default"
data-competitor-card-odds-flash-intervalFlash interval in milliseconds. Ignored unless the mode is "flash"Positive integer3000
data-competitor-card-odds-polling-intervalOdds poll interval in millisecondsPositive integer30000
data-competitor-card-odds-operatorsComma-separated operator config ids, in preference order — the card shows one operator, the first with a complete markete.g. "betano-bg,efbet-bg"First operator with prices
data-competitor-card-odds-affiliate-idAffiliate id substituted into every operator URL carrying an {affiliate_id} placeholderAffiliate id stringNone
data-competitor-card-odds-affiliate-idsJSON object of per-operator affiliate ids. Wins over data-competitor-card-odds-affiliate-ide.g. '{"betano-bg":"aff-123"}'None
data-competitor-card-show-fixturesRender the Fixtures header CTA and its inline panel"true", "false"true
data-competitor-card-show-squadRender the Squad header CTA and its panel. Teams only — inert on an athlete"true", "false"true
data-competitor-card-squad-background-gradientCSS background for the expanded player cardAny CSS backgroundSoft wash of the competitor branding
data-competitor-card-show-season-statsRender the Season stats header CTA and its table. Athletes only — inert on a team"true", "false"true

Per-element attributes override the global competitorCard config field by field, including inside its nested objects (form, featuredMatch, odds and its affiliateIds, fixtures, squad, stats, labels) — setting data-competitor-card-form-max-items keeps a globally configured form.matchCTA.

Templates

data-competitor-card-template picks the arrangement of the same card — never its behaviour.

ValueLayout
"standard" (default)Bordered card, washed header strip, labelled CTAs; headline tile beside the bars
"hero"Branded gradient header carrying the CTAs, the headline tiles and the form
"horizontal"Persistent branded rail (identity, CTAs, competition switcher) beside a column that swaps Overview / Fixtures / the second panel
"compact"Sidebar width — icon-only CTAs, a single bordered stats row, outcome dots, a one-line fixture

The card resolves its responsive layout against its container, not the viewport, so an embed in a 320px sidebar stacks correctly on a desktop page.

Teams and Athletes

Team (fb:t:…)Athlete (fb:p:…)
StatisticsPoints tile, W/D/L bar, goals scored/conceded, goal differenceGoals tile with a per-90 rate, minutes and appearances bars, stat chips
Second CTASquad — grouped by position, each row expanding into a player cardSeason stats — every statistic, one column per competition plus a total
Form / fixturesThe club's ownThe player's club's, captioned with the club's name
BrandingThe club's coloursThe club's colours — a player declares none

The competition switcher is the card's single scope control: it filters the statistics, the form, the featured match and the fixtures panel together, and opens on the domestic league rather than on All. The card covers one season — fixtures from the previous season are left out.

Row CTAs

Every clickable row resolves through a CTA you configure. No URLs are baked in: a row with no CTA is inert, with no hover state and no pointer cursor.

RowAttribute prefixConfig field
A form tiledata-competitor-card-form-match-ctaform.matchCTA
The featured matchdata-competitor-card-featured-match-ctafeaturedMatch.matchCTA
A fixture / result rowdata-competitor-card-fixtures-match-ctafixtures.matchCTA
The "Full profile" CTA of a squad playerdata-competitor-card-squad-player-ctasquad.playerCTA

Each prefix takes three suffixes:

SuffixDescriptionOptions/Format
-urlURL template (see placeholders below). The row renders as an <a href>, so it stays crawlableURL string
-targetLink target"_blank", "_self"
-onclickInline JavaScript run on click. With a -url as well, the navigation is prevented so your router handles itJavaScript code string

-url substitutes the placeholders each row can fill, URL-encoded: {matchId} {competitorId} {opponentId} {competitionId} {seasonId} {date} {athleteId}. A placeholder a row cannot fill resolves to an empty string. On an athlete's card {competitorId} is the club the fixture belongs to, and {athleteId} is the player.

<div
	data-component="fu-widget"
	data-content-type="competitor-card"
	data-content-id="fb:t:8205"
	data-competitor-card-fixtures-match-cta-url="/football/match/{matchId}"
	data-competitor-card-squad-player-cta-url="/football/player/{athleteId}"
	data-competitor-card-squad-player-cta-target="_blank"
></div>
⚠️

-onclick is evaluated as code, like data-signin-cta-onclick. Only use it in markup your own site authors — never with values that come from user input or a CMS field.

Betting Odds

Outright prices for the upcoming featured match. The market follows the sport: a fixture that can be drawn is priced three ways (FT_1X2 — 1 · X · 2), one that cannot (American football, basketball, tennis) two ways (WINNER_OT — 1 · 2). When no operator has a complete market the strip simply does not render. The operator's own link opens on click either way.

The card shows one operator — the first in data-competitor-card-odds-operators that publishes a complete market — so the list is a preference order, not a filter that widens the strip. data-competitor-card-odds-affiliate-id is substituted into every operator URL carrying an {affiliate_id} placeholder, so clicks from the odds strip are attributed to you (the same field as the Betslip's affiliateId); data-competitor-card-odds-affiliate-ids sets one per operator and wins over it.

The card owns no betslip. Set data-competitor-card-add-to-betslip="true" to push a clicked price into the Betslip widget on the same page as a selection ({matchId}:{market}:{outcome} — e.g. fb:m:123:FT_1X2:1 — the same id FuWidget.betslip.setSelection takes). It is off by default because without a Betslip widget on the page the selection has nowhere to go.

<div
	data-component="fu-widget"
	data-content-type="competitor-card"
	data-content-id="fb:t:8205"
	data-competitor-card-add-to-betslip="true"
></div>
<div data-component="fu-widget" data-content-type="betslip"></div>

To observe clicks yourself — for your own betslip or for analytics — pass competitorCard.onAddToBetslip in FuWidget.init(). It receives { matchId, market, pick: "1" | "X" | "2", odd }, where market is the code the price came from ("FT_1X2" or "WINNER_OT") — pass it through rather than assuming 1X2. It runs whether or not addToBetslip is on. It is programmatic config only; there is no data-attribute equivalent.

Global Configuration

Set defaults for all Competitor Card widgets in FuWidget.init():

FuWidget.init({
	// ... other config
	competitorCard: {
		template: "hero",
		showCountry: true,
		titlePosition: "left",
		showCompetitionSwitcher: true,
		hasBranding: true,
		liveRefresh: true,
		refreshInterval: 30000,
		form: { maxItems: 5, matchCTA: { url: "/football/match/{matchId}" } },
		featuredMatch: { type: "next", toggle: true, matchCTA: { url: "/football/match/{matchId}" } },
		odds: {
			mode: "default",
			pollingInterval: 30000,
			operators: ["betano-bg", "efbet-bg"], // Preference order — the card shows one operator
			affiliateId: "aff-123", // Substituted into operator URLs carrying {affiliate_id}
			affiliateIds: { "efbet-bg": "aff-456" }, // Optional: per operator, wins over affiliateId
		},
		fixtures: { matchCTA: { url: "/football/match/{matchId}" } },
		squad: {
			playerCTA: {
				url: "/football/player/{athleteId}",
				onClick: () => router.push(/* ... */), // Optional: handle the click in your app instead of navigating
			},
		},
		labels: { squad: "Players" },
		addToBetslip: true,
		onAddToBetslip: (selection) => console.log(selection), // Optional: observe clicked odds prices
	},
});

Examples

Player

<div
	data-component="fu-widget"
	data-content-type="competitor-card"
	data-content-id="fb:p:48824"
	data-competitor-card-template="hero"
	data-competitor-card-fixtures-match-cta-url="/football/match/{matchId}"
></div>

Sidebar

<div
	data-component="fu-widget"
	data-content-type="competitor-card"
	data-content-id="fb:t:8205"
	data-competitor-card-template="compact"
	data-competitor-card-show-squad="false"
></div>

Last Result, No Odds or Branding

<div
	data-component="fu-widget"
	data-content-type="competitor-card"
	data-content-id="fb:t:8205"
	data-competitor-card-featured-match-type="last"
	data-competitor-card-featured-match-toggle="false"
	data-competitor-card-show-odds="false"
	data-competitor-card-has-branding="false"
></div>

Features

  • Four templates — standard, hero, horizontal, compact — changing the arrangement and density, never the behaviour
  • Teams and athletes from one widget, each with its own statistics and second panel (Squad / Season stats)
  • Competition switcher as the card's single scope control, filtering statistics, form, featured match and fixtures together
  • Recent form with per-fixture tooltips, and a featured match with a Last | Next toggle
  • Sport-aware outright odds (FT_1X2 or WINNER_OT) under an upcoming featured match, with operator preference, affiliate attribution, an optional flash mode and opt-in Betslip integration
  • Live badge with the match minute while a fixture is in progress, plus optional polling
  • Competitor branding on the header, headline tile and panels, with automatic contrast handling
  • Every clickable row resolves through a CTA you configure — no URLs are baked in

Did this page help you?