If somebody wants check your premier rating in widget(similar to FACEIT widget) here you go, easy setup, just download scriptable, and I’ll post full code down below.

// Variables used by Scriptable.

// These must be at the very top of the file. Do not edit.

// icon-color: deep-blue; icon-glyph: crosshairs;

/*

* CS2 PREMIER STATS WIDGET

* * Displays your Rating, Global Rank Tier, K/D, HLTV Rating, and Win Rate.

* Uses aggressive caching to prevent timeouts on the iOS Home Screen.

* * HOW TO USE:

* 1. Go to https://csstats.gg/ and find your profile.

* 2. Copy your STEAM ID (the numbers in the URL).

* 3. Add this script to a widget.

* 4. Long press the widget -> Edit Widget.

* 5. Paste your STEAM ID into the "Parameter" field.

* * Alternatively, enter your ID in the CONFIG section below.

*/

// — CONFIGURATION —

// Enter your Steam ID here if you don't want to use the Widget Parameter

const DEFAULT_STEAM_ID = "";

// — MAIN LOGIC —

const widgetParam = args.widgetParameter;

const steamID = widgetParam || DEFAULT_STEAM_ID;

if (!steamID || steamID === "") {

let w = createSetupWidget();

if (!config.runsInWidget) await w.presentSmall();

Script.setWidget(w);

Script.complete();

} else {

await runWidget(steamID);

}

async function runWidget(id) {

const url = "https://csstats.gg/player/" + id;

const fm = FileManager.local();

// Unique cache file per Steam ID allows multiple widgets for different players

const cachePath = fm.joinPath(fm.documentsDirectory(), `csstats_cache_${id}.json`);

// 1. Load Cache

let cachedData = null;

if (fm.fileExists(cachePath)) {

cachedData = JSON.parse(fm.readString(cachePath));

}

let finalData = cachedData;

try {

// 2. Fetch Fresh Data (Race against 13s timeout)

let freshData = await Promise.race([

getFreshStats(url),

new Promise((_, reject) => Timer.schedule(13000, false, () => reject("TIMEOUT")))

]);

// 3. Update Cache if successful

if (freshData && freshData.rating !== "0") {

finalData = freshData;

fm.writeString(cachePath, JSON.stringify(finalData));

}

} catch (e) {

// Fallback to cache on timeout/error

if (finalData) finalData.isCached = true;

}

// Fallback for very first run with no internet

if (!finalData) {

finalData = { rating: "0", kd: "—", hltv: "—", wr: "—", timestamp: new Date().getTime() };

}

let w = createStatsWidget(finalData, id);

if (!config.runsInWidget) await w.presentSmall();

Script.setWidget(w);

Script.complete();

}

// — SCRAPER —

async function getFreshStats(url) {

let wv = new WebView();

await wv.loadURL(url);

let jsonString = await wv.evaluateJavaScript(`

var maxAttempts = 22; // ~11 seconds

var interval = setInterval(function() {

maxAttempts–;

var text = document.body.innerText;

// Wait for essential keywords or timeout

if ((text.includes("Rating") && text.includes("K/D")) || maxAttempts <= 0) {

clearInterval(interval);

var ratingMatch = text.match(/([0-9]{1,3}[, ][0-9]{3})/);

var kdMatch = text.match(/K\\/?D(?:\\s*Ratio)?[\\s\\n]*([0-9]+\\.[0-9]+)/i);

var hltvMatch = text.match(/(?:Rating 2\\.0|HLTV Rating|Rating)[\\s\\n]*([0-9]+\\.[0-9]+)/i);

var wrMatch = text.match(/Win Rate[\\s\\n]*([0-9]+%)/i);

var result = {

success: true,

timestamp: new Date().getTime(),

rating: ratingMatch ? ratingMatch[1].replace(/[^0-9]/g, "") : "0",

kd: kdMatch ? kdMatch[1] : "—",

hltv: hltvMatch ? hltvMatch[1] : "—",

wr: wrMatch ? wrMatch[1] : "—"

};

completion(JSON.stringify(result));

}

}, 500);

`, true);

return JSON.parse(jsonString);

}

// — WIDGET UI —

function createStatsWidget(d, id) {

let num = parseInt(d.rating);

// Dynamic Theme

let theme = { m: "#5665e8", bg: "#0d0e17" }; // Blue <15k

if (num >= 30000) theme = { m: "#f7d93d", bg: "#1a160d" }; // Gold

else if (num >= 25000) theme = { m: "#eb4b4b", bg: "#1a0d0d" }; // Red

else if (num >= 20000) theme = { m: "#d32de6", bg: "#150b17" }; // Pink

else if (num >= 15000) theme = { m: "#9e4dd6", bg: "#110a17" }; // Purple

let w = new ListWidget();

w.backgroundColor = new Color(theme.bg);

w.setPadding(10, 8, 10, 8);

w.url = "https://csstats.gg/player/" + id;

// Header

let h = w.addStack();

h.centerAlignContent();

let tag = h.addStack();

tag.backgroundColor = new Color(theme.m, 0.2);

tag.setPadding(3, 6, 3, 6); tag.cornerRadius = 4;

let tagT = tag.addText("CS2 PREMIER");

tagT.font = Font.blackSystemFont(8); tagT.textColor = new Color(theme.m);

h.addSpacer();

// Status & Time

let date = new Date(d.timestamp || new Date().getTime());

let timeStr = date.getHours().toString().padStart(2, '0') + ":" + date.getMinutes().toString().padStart(2, '0');

let statusColor = d.isCached ? Color.orange() : new Color("#ade347");

if (d.rating === "0") statusColor = Color.red();

let liveDot = h.addText("●");

liveDot.font = Font.blackSystemFont(6);

liveDot.textColor = statusColor;

h.addSpacer(3);

let liveText = h.addText(timeStr);

liveText.font = Font.boldSystemFont(8);

liveText.textColor = Color.white();

liveText.opacity = 0.6;

w.addSpacer(10);

// Rating

let rStack = w.addStack();

rStack.centerAlignContent();

let rText = rStack.addText(num > 0 ? num.toLocaleString().replace(/,/g, ' ') : "LOADING…");

rText.font = Font.italicSystemFont(40); rText.textColor = Color.white();

rText.shadowColor = new Color(theme.m, 0.6); rText.shadowRadius = 4; rText.shadowOffset = new Point(0, 2);

rText.minimumScaleFactor = 0.8;

w.addSpacer(12);

// Stats Row

let sRow = w.addStack();

sRow.centerAlignContent();

sRow.spacing = 3;

let addStatPill = (label, value) => {

let s = sRow.addStack();

s.backgroundColor = new Color("#ffffff", 0.08);

s.setPadding(3, 4, 3, 4); s.cornerRadius = 5; s.centerAlignContent();

let l = s.addText(label);

l.font = Font.boldSystemFont(8); l.textColor = new Color("#ffffff", 0.5);

s.addSpacer(2);

let v = s.addText(value);

v.font = Font.boldSystemFont(9); v.textColor = Color.white();

v.lineLimit = 1; v.minimumScaleFactor = 0.7;

}

addStatPill("KD", d.kd);

addStatPill("HLTV", d.hltv);

addStatPill("WR", d.wr);

w.addSpacer(12);

// Progress Bar

let next = Math.ceil((num + 1) / 5000) * 5000;

if (num === 0) next = 5000;

let barBg = w.addStack();

barBg.size = new Size(0, 5); barBg.backgroundColor = new Color("#ffffff", 0.1); barBg.cornerRadius = 2.5;

let pct = (num % 5000) / 5000;

if (pct < 0) pct = 0;

let fill = barBg.addStack();

fill.size = new Size(135 * pct, 5);

fill.backgroundColor = new Color(theme.m); fill.cornerRadius = 2.5;

w.addSpacer(6);

// Footer

let fStack = w.addStack();

let foot = fStack.addText(`${next – num} TO NEXT RANK`);

foot.font = Font.heavySystemFont(7); foot.textColor = new Color("#ffffff", 0.4);

fStack.addSpacer();

let rankName = fStack.addText(`TIER ${Math.floor(next/1000)}K`);

rankName.font = Font.heavySystemFont(7); rankName.textColor = new Color(theme.m, 0.8);

return w;

}

function createSetupWidget() {

let w = new ListWidget();

w.backgroundColor = new Color("#1a1a1a");

let t = w.addText("⚠️ SETUP REQUIRED");

t.font = Font.boldSystemFont(12);

t.textColor = Color.red();

w.addSpacer(10);

let msg = w.addText("Long press widget > Edit Widget > Set 'Parameter' to your Steam ID.");

msg.font = Font.systemFont(10);

return w;

}