Predictor
A season-long score predictor with Play, Leaderboard, Private Leagues, Rules, and Prizes tabs, plus a compact single-match embed template.
Football score predictor widget with two templates: the default multi-tab interface (match predictions, global leaderboard, private leagues, game rules, and prizes) for a season-long engagement tool, and embed — a compact single-match card designed to sit inside an article. Users submit match score predictions across grouped matchweeks, track their standing on a global leaderboard, create or join private leagues, read game rules, and view prizes — all within a single embedded widget.
<div
data-component="fu-widget"
data-content-type="predictor"
data-content-id="your-predictor-template-id"
data-predictor-tabs="play,leaderboard,private-leagues,rules,prizes"
data-signin-cta-label="Sign in to Predict"
data-signin-cta-onclick="showSignInModal()"
data-predictor-match-card-bg-image-url="https://example.com/stadium-bg.jpg"
data-predictor-consents='[{"consentId":"tos","body":"I agree to the <a href=\"#\" target=\"_blank\" rel=\"noopener\">Terms of Service</a>","required":true,"defaultChecked":false}]'
></div>Configuration Attributes
| Attribute | Description | Options/Format | Default |
|---|---|---|---|
data-predictor-template | Which presentation to render | "standard", "embed" | "standard" |
data-predictor-tabs | Comma-separated list of tabs to enable | "play,leaderboard,private-leagues,rules,prizes" | All tabs |
data-signin-cta-label | Override the sign-in button label | Any string | Translated default |
data-signin-cta-onclick | JavaScript code to execute on sign-in click | JavaScript code | None |
data-signin-cta-url | Direct URL for the sign-in CTA | Valid URL | None |
data-signin-cta-target | Link target for the sign-in CTA URL | "_self", "_blank" | "_self" |
data-predictor-match-card-bg-image-url | Background image URL for match prediction cards | Valid image URL | Global config |
data-predictor-consents | JSON array of consent definitions required before predicting | Array of consent objects (see below) | Global config |
data-predictor-betslip | JSON object to enable betslip integration inside Predictor | PredictorBetslipConfig object (see below) | Global config |
data-predictor-cutoff-minutes | Minutes before kickoff when a match closes for predicting. 15 is also the minimum | Integer ≥ 15 | 15 |
Header Banner
Applies to
data-predictor-template="standard"only.
The hero banner paints the template image (or the global defaultImagePlaceholderUrl) over the brand gradient. By default it is full width and its height comes from the title and description, so tall or square artwork gets cropped to a thin strip. These attributes size the banner to the artwork instead.
| Attribute | Description | Options/Format | Default |
|---|---|---|---|
data-predictor-header-aspect-ratio | Height as a ratio of the banner's width. Preferred over a fixed height (see below) | e.g. "3 / 1", "4 / 1" | None |
data-predictor-header-height | Fixed banner height, any CSS length. Wins over the aspect ratio | e.g. "240px", "15em" | Title + description |
data-predictor-header-min-height | Height floor; the banner still grows for a long description | Any CSS length | None |
data-predictor-header-max-width | Caps the artwork's width and centres it. The gradient band stays full width | Any CSS length | Full width |
data-predictor-header-image-fit | "cover" fills the banner and crops; "contain" fits the whole image | "cover", "contain" | "cover" |
data-predictor-header-image-align | CSS background-position for the artwork | e.g. "top", "center 33%" | "center" |
data-predictor-header-background | What sits around the image — any CSS background value | Colour or gradient | Theme gradient |
data-predictor-header-text-position | Where the title/description sit when the banner is taller than they are | "top", "center", "bottom" | "center" |
data-predictor-header-hide-text | Hide the title/description, for artwork that already carries them | "true", "false" | false |
<!-- Wide artwork (3:1-4:1) filling the band edge to edge -->
<div
data-component="fu-widget"
data-content-type="predictor"
data-content-id="your-predictor-template-id"
data-predictor-header-aspect-ratio="4 / 1"
></div>
<!-- A 3:2 poster that already carries its own headline -->
<div
data-component="fu-widget"
data-content-type="predictor"
data-content-id="your-predictor-template-id"
data-predictor-header-max-width="1000px"
data-predictor-header-aspect-ratio="3 / 1"
data-predictor-header-image-align="center 33%"
data-predictor-header-hide-text="true"
></div>Prefer the aspect ratio over a fixed height. "cover" scales the image to the banner's width, so with a fixed pixel height the visible slice shrinks as the page gets wider — the same 240px that frames the artwork on a 900px page shows a magnified fragment of it on a 1900px one. An aspect ratio ties height to width, so the same slice survives at every screen size. A 3:2 image renders 1.5× the banner's width in height, so a 3 / 1 band shows half of it, 4 / 1 shows 37%, 6 / 1 shows 25%; the visible window runs from data-predictor-header-image-align × (1 − visible fraction) downward. Cap the max width when the resulting height is too tall — full width, short, and the whole message visible cannot all hold at once for a poster-shaped asset.
data-predictor-header-image-fit="contain" is the alternative: the whole image at whatever height you set, with the space either side filled by a blurred, darkened blow-up of the same artwork. It suits busy photographic backdrops; flat colours and hard graphic edges tend to smear. Use data-predictor-header-background to replace that backdrop with a flat colour or your own gradient.
Use
emor percentage lengths rather thanrem—remresolves against the host page's root font size, which the widget does not control.
A single data-predictor-header-* attribute on an element replaces the whole global predictor.header object for that widget — the two are not merged field by field. Repeat the fields you want to keep as attributes.
Global configuration:
FuWidget.init({
// ... other config
predictor: {
header: {
aspectRatio: "3 / 1", // Optional: height as a ratio of the banner's width
maxWidth: "1000px", // Optional: caps the artwork width and centres it
imageAlign: "center 33%", // Optional: CSS background-position (default: "center")
hideText: true, // Optional: hide the title/description (default: false)
},
cutoffMinutes: 15, // Optional: minutes before kickoff when a match closes (default and minimum: 15)
},
});Templates
Predictor supports two presentations, chosen via data-predictor-template. Unlike the shared WidgetTemplate enum used by most other widgets, Predictor's template is a plain string union.
| Template | Use case |
|---|---|
"standard" (default) | The full multi-tab interface — Play, Leaderboard, Private Leagues, Rules, Prizes. |
"embed" | A single upcoming match rendered as a compact card, meant to be dropped inside an article. No tabs, no leaderboard. |
<div
data-component="fu-widget"
data-content-type="predictor"
data-content-id="your-predictor-template-id"
data-predictor-template="embed"
data-predictor-embed-image-position="left"
data-predictor-embed-match-id="fb:m:451634"
data-predictor-embed-success-title="Prediction submitted!"
data-predictor-embed-success-description="Keep playing for a chance to win amazing prizes."
data-predictor-embed-success-cta-label="Play Now"
data-predictor-embed-success-cta-url="https://your-site.com/predictor"
data-predictor-embed-success-cta-target="_blank"
></div>Embed Attributes (only read when data-predictor-template="embed"):
| Attribute | Description | Options/Format | Default |
|---|---|---|---|
data-predictor-embed-image-position | Which side the image renders on; description takes the other side | "left", "right" | "right" |
data-predictor-embed-match-id | Pin a specific match | Match id | Soonest upcoming match |
data-predictor-embed-success-title | Title shown below the match card after a prediction is submitted | Any string | None |
data-predictor-embed-success-description | Description shown alongside the success title | Any string | None |
data-predictor-embed-success-cta-label | Success CTA button label | Any string | None |
data-predictor-embed-success-cta-onclick | Success CTA JavaScript function | JavaScript code | None |
data-predictor-embed-success-cta-url | Success CTA redirect URL | Valid URL | None |
data-predictor-embed-success-cta-target | Success CTA link target | "_self", "_blank" | "_self" |
Omit all
data-predictor-embed-success-*attributes to show nothing extra after a prediction is submitted.
Global configuration:
FuWidget.init({
// ... other config
predictor: {
template: "embed",
embed: {
imagePosition: "left",
matchId: "fb:m:451634",
successMessage: {
title: "Prediction submitted!",
description: "Keep playing for a chance to win amazing prizes.",
cta: {
defaultLabel: "Play Now",
url: "https://your-site.com/predictor",
target: "_blank",
},
},
},
},
});Tabs
Applies to
data-predictor-template="standard"only (or when the attribute is omitted, since"standard"is the default).
All tabs are shown by default. Use data-predictor-tabs to restrict which tabs are visible. The order in the attribute determines the display order.
| Tab value | Description |
|---|---|
play | Main prediction interface — submit match score forecasts |
leaderboard | Global rankings and user standings with pagination |
private-leagues | Create and join private leagues to compete with friends |
rules | Searchable game rules and scoring system |
prizes | Prize distribution and rewards information |
Consent Configuration
Require users to accept consent agreements before submitting their first prediction. Configure consents globally or per-widget using data-predictor-consents. Required consents block progression until accepted; optional consents are shown in the same modal but do not block it.
Global configuration:
FuWidget.init({
// ... other config
predictor: {
consents: [
{
consentId: "tos",
body: `I agree to the <a href="#" target="_blank" rel="noopener">Terms of Service</a>`,
required: true,
defaultChecked: false,
},
],
},
});Per-widget override:
<div
data-component="fu-widget"
data-content-type="predictor"
data-content-id="your-predictor-template-id"
data-predictor-consents='[{"consentId":"tos","body":"I agree to the <a href=\"#\" target=\"_blank\" rel=\"noopener\">Terms of Service</a>","required":true,"defaultChecked":false}]'
></div>Consent Object Fields:
| Field | Type | Description |
|---|---|---|
consentId | string | Unique identifier for the consent (e.g. "tos", "marketing") |
body | string | Text or HTML content of the consent label |
required | boolean | When true, the user must accept before they can predict |
defaultChecked | boolean | Pre-check the consent checkbox on load |
Betslip Integration
The Predictor widget has built-in betslip support. When enabled, users can add selections directly from the prediction interface and place bets alongside their predictions.
The trigger field controls which predictions open the betslip:
| Value | Description |
|---|---|
"predictions-only" | Betslip appears only for predictions that carry live odds |
"odds-only" | Betslip appears for any odds, regardless of prediction state |
Global configuration:
FuWidget.init({
// ... other config
predictor: {
betslip: {
trigger: "predictions-only",
position: "bottom-right",
currency: "USD",
ctaUrlTemplate: "https://bookmaker.com/betslip?s={SELECTIONS}",
},
},
});Per-widget override:
<div
data-component="fu-widget"
data-content-type="predictor"
data-content-id="your-predictor-template-id"
data-predictor-betslip='{"trigger":"predictions-only","position":"bottom-right","currency":"USD"}'
></div>PredictorBetslipConfig fields:
| Field | Type | Description |
|---|---|---|
trigger | string | When to activate the betslip: "predictions-only" or "odds-only" |
position | BetslipPosition | Widget position on the page (same options as standalone Betslip) |
maxSelections | number | Maximum allowed selections |
stakePresets | number[] | Quick-stake preset amounts |
oddsPollingInterval | number | Odds refresh interval in milliseconds |
currency | string | Currency label |
ctaUrlTemplate | string | URL for the place-bet CTA |
brandingLogoUrl | string | Bookmaker or sponsor logo URL |
labels | BetslipLabels | Override displayed text (see the Betslip widget page) |
Authentication and Sign-in
The widget automatically detects user authentication status. When a user is not authenticated, a sign-in prompt is shown in the Play tab. Configure the sign-in CTA globally or per-widget using the same signInCTA configuration as other widgets.
FuWidget.init({
// ... other config
signInCTA: {
defaultLabel: "Sign in to Predict",
onClick: () => {
window.location.href = "/signin";
},
},
});Features
- Two templates:
"standard"(multi-tab) and"embed"(single-match article card) — see Templates - Multi-tab interface: Play, Leaderboard, Private Leagues, Rules, and Prizes (
"standard"only) - Configurable hero banner sizing and framing — see Header Banner
- Season-long score prediction for grouped matchweeks
- Configurable prediction cutoff before kickoff
- Global leaderboard with paginated standings and user rank highlighting
- Private leagues — create and join custom competitive groups
- Consent management with required/optional consent gates
- Authentication-aware UI with configurable sign-in CTA
- Custom match card background image
- Built-in betslip integration for placing bets alongside predictions
- Custom theming and multi-language support
Updated 6 days ago
