PageSourceSearch

https://www.automarkhistory.com/

html automarkhistory.com collected 2026-09-27 22:06:47 UTC 152,252 bytes, 2,226 lines download raw bytes

1<!DOCTYPE html>
2<html lang="vi">
3
4<head>
5  <meta charset="UTF-8" />
6  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7  <link rel="preconnect" href="https://fonts.googleapis.com" />
8  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
9  <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700&display=swap" rel="stylesheet" />
10  <link rel="stylesheet" href="/wp-content/themes/cakhiatv/style.css" />
11  <meta name="google-site-verification" content="N4PHm8858vvS25ZaozakiBR8Rqy-cmJpCdu8VHCbLRQ" />
12<meta name="google-site-verification" content="aZEowe-ibxNxKD09Gs1mSbrQ7Lc83SSXderlpnwvDCE" />
13<meta name="google-site-verification" content="xZ47nKKCrBO5dAJUU7-o9jLaP0PsFrI9zlgm-odcJOU" />
14<meta name="google-site-verification" content="Zy4loSo9PLVU1TsNjBfuqVm8SqsiF5qtYoy0LlS-5oI" />
15<meta name="google-site-verification" content="t3dflyBr7raYAR-vsb_bRbrip94gKM-2V3a3FWHfNc4" />
16<meta name="google-site-verification" content="KGxk3PXsTaGy9SiO1hcr3ma1OfueAusFMexB4hiBe_Y" />
17<meta name="google-site-verification" content="qg1L9hymWrNWdhFzphpFQSmYwRkht-XfLQw
175dDRW17E" />
18<meta name="google-site-verification" content="hefNkr9RbURzgVGAiv4hmP7ZtR80bIqdWDa8TrlsGsA" />
19<meta name="google-site-verification" content="hEC36AuDDZoWtXwBr6wzeDifmWN99ZmvTMhz6-Xvj88" />
20<!-- Google tag (tổng) -->
vendor: 65 bytes, lines 20-21
20
21<script async src="https://www.googletagmanager.com/gtag/js?id=
21G-V8GXMSME5N
vendor: 13 bytes, line 21
21"></script>
22<script>
23  
vendor: 138 bytes, lines 23-27
23window.dataLayer = window.dataLayer || [];
24  function gtag(){dataLayer.push(arguments);}
25  gtag('js', new Date());
26
27  gtag('config', '
27G-V8GXMSME5N
vendor: 5 bytes, line 27
27');
28</script>
28
29 
29<script type="application/ld+json">
30{
31  "@context": "https://schema.org",
32  "@type": "BreadcrumbList",
33  "itemListElement": [
34
35         {
36        "@type": "ListItem",
37        "position": 1,
38        "name": "Trang chá»§",
39        "item": "https://www.automarkhistory.com"
40      },
41
42      {
43        "@type": "ListItem",
44        "position": 1,
45        "name": "Saoketv Link chính thức",
46        "item": "https://www.automarkhistory.com/tin-tuc"
47      }
48
49    
50  ]
51}
52</script>
52
53  	<style>img:is([sizes="auto" i], [sizes^="auto," i]) { contain-intrinsic-size: 3000px 1500px }</style>
54	
55<!-- Tối ưu hóa công cụ tìm kiếm bởi Rank Math PRO - https://rankmath.com/ -->
56<title>Saoketv - Trang xem trực tiếp bóng đá rõ nét, ổn định 24/7</title>
57<meta name="description" content="Saoketv trang xem trực tiếp bóng đá miễn phí, chất lượng Full HD, tốc độ cao, không giật lag. Cập nhật link xem bóng đá hôm nay nhanh nhất, đầy đủ các giải đấu."/>
58<meta name="robots" content="follow, index, max-snippet:-1, max-video-preview:-1, max-image-preview:large"/>
59<link rel="canonical" href="https://www.automarkhistory.com/" />
60<meta property="og:locale" content="vi_VN" />
61<meta property="og:type" content="website" />
62<meta property="og:title" content="Saoketv - Trang xem trực tiếp bóng đá rõ nét, ổn định 24/7" />
63<meta property="og:description" content="Saoketv trang xem trực tiếp bóng đá miễn phí, chất lượng Full HD, tốc độ cao, không giật lag. Cập nhật link xem bóng đá hôm nay nhanh nhất, đầy đủ các giải đấu." />
64<meta property="og:url" content="https://www.automarkhistory.com/" />
65<meta property="og:site_name" content="Saoketv" />
66<meta property="og:updated_time" content="2026-02-06T23:39:49+07:00" />
67<meta property="og:image" content="https://cdn.automarkhistory.com/wp-content/uploads/2025/12/bi-quyet-khien-saoketv-tro-thanh-trang-xem-bong-da-duoc-ua-chuong-1.jpg" />
68<meta property="og:image:secure_url" content="https://cdn.automarkhistory.com/wp-content/uploads/2025/12/bi-quyet-khien-saoketv-tro-thanh-trang-xem-bong-da-duoc-ua-chuong-1.jpg" />
69<meta property="og:image:width" content="800" />
70<meta property="og:image:height" content="400" />
71<meta property="og:image:alt" content="Saoketv" />
72<meta property="og:image:type" content="image/jpeg" />
73<meta property="article:published_time" content="2025-09-08T14:05:35+07:00" />
74<meta property="article:modified_time" content="2026-02-06T23:39:49+07:00" />
75<meta name="twitter:card" content="summary_large_image" />
76<meta name="twitter:title" content="Saoketv - Trang xem trực tiếp bóng đá rõ nét, ổn định 24/7" />
77<meta name="twitter:description" content="Saoketv trang xem trực tiếp bóng đá miễn phí, chất lượng Full HD, tốc độ cao, không giật lag. Cập nhật link xem bóng đá hôm nay nhanh nhất, đầy đủ các giải đấu." />
78<meta name="twitter:image" content="https://cdn.automarkhistory.com/wp-content/uploads/2025/12/bi-quyet-khien-saoketv-tro-thanh-trang-xem-bong-da-duoc-ua-chuong-1.jpg" />
79<meta name="twitter:label1" content="Được viết bởi" />
80<meta name="twitter:data1" content="Admin" />
81<meta name="twitter:label2" content="Thời gian để đọc" />
82<meta name="twitter:data2" content="25 phút" />
83<script type="application/ld+json" class="rank-math-schema-pro">{"@context":"https://schema.org","@graph":[{"@type":["Organization","Person"],"@id":"https://www.automarkhistory.com/#person","name":"Saoketv","url":"https://gameswebstore.com/"},{"@type":"WebSite","@id":"https://www.automarkhistory.com/#website","url":"https://www.automarkhistory.com","name":"Saoketv","publisher":{"@id":"https://www.automarkhistory.com/#person"},"inLanguage":"vi","potentialAction":{"@type":"SearchAction","target":"https://www.automarkhistory.com/?s={search_term_string}","query-input":"required name=search_term_string"}},{"@type":"ImageObject","@id":"https://cdn.automarkhistory.com/wp-content/uploads/2025/12/bi-quyet-khien-saoketv-tro-thanh-trang-xem-bong-da-duoc-ua-chuong-1.jpg","url":"https://cdn.automarkhistory.com/wp-content/uploads/2025/12/bi-quyet-khien-saoketv-tro-thanh-trang-xem-bong-da-duoc-ua-chuong-1.jpg","width":"800","height":"400","inLanguage":"vi"},{"@type":"WebPage","@id":"https://www.automarkhistory.com/#webpage","url":"https://www.automarkhistory.com/","name":"Saoketv - Trang xem tr\u1ef1c ti\u1ebfp b\u00f3ng \u0111\u00e1 r\u00f5 n\u00e9t, \u1ed5n \u0111\u1ecbnh 24/7","datePublished":"2025-09-08T14:05:35+07:00","dateModified":"2026-02-06T23:39:49+07:00","about":{"@id":"https://www.automarkhistory.com/#person"},"isPartOf":{"@id":"https://www.automarkhistory.com/#website"},"primaryImageOfPage":{"@id":"https://cdn.automarkhistory.com/wp-content/uploads/2025/12/bi-quyet-khien-saoketv-tro-thanh-trang-xem-bong-da-duoc-ua-chuong-1.jpg"},"inLanguage":"vi"},{"@type":"Person","@id":"https://www.automarkhistory.com/tac-gia/seo/","name":"Admin","url":"https://www.automarkhistory.com/tac-gia/seo/","image":{"@type":"ImageObject","@id":"https://secure.gravatar.com/avatar/ad61670926c47f2b732ffa3d7bcfeea37e9afab93cf5d1aaf83df66abc167a69?s=96&amp;d=mm&amp;r=g","url":"https://secure.gravatar.com/avatar/ad61670926c47f2b732ffa3d7bcfeea37e9afab93cf5d1aaf83df66abc167a69?s=96&amp;d=mm&amp;r=g","caption":"Admin","inLanguage":"vi"}},{"@type":"Article","headline":"Saoketv - Trang xem tr\u1ef1c ti\u1ebfp b\u00f3ng \u0111\u00e1 r\u00f5 n\u00e9t, \u1ed5n \u0111\u1ecbnh 24/7","keywords":"Saoketv","datePublished":"2025-09-08T14:05:35+07:00","dateModified":"2026-02-06T23:39:49+07:00","author":{"@id":"https://www.automarkhistory.com/tac-gia/seo/","name":"Admin"},"publisher":{"@id":"https://www.automarkhistory.com/#person"},"description":"Saoketv trang xem tr\u1ef1c ti\u1ebfp b\u00f3ng \u0111\u00e1 mi\u1ec5n ph\u00ed, ch\u1ea5t l\u01b0\u1ee3ng Full HD, t\u1ed1c \u0111\u1ed9 cao, kh\u00f4ng gi\u1eadt lag. C\u1eadp nh\u1eadt link xem b\u00f3ng \u0111\u00e1 h\u00f4m nay nhanh nh\u1ea5t, \u0111\u1ea7y \u0111\u1ee7 c\u00e1c gi\u1ea3i \u0111\u1ea5u.","name":"Saoketv - Trang xem tr\u1ef1c ti\u1ebfp b\u00f3ng \u0111\u00e1 r\u00f5 n\u00e9t, \u1ed5n \u0111\u1ecbnh 24/7","@id":"https://www.automarkhistory.com/#richSnippet","isPartOf":{"@id":"https://www.automarkhistory.com/#webpage"},"image":{"@id":"https://cdn.automarkhistory.com/wp-content/uploads/2025/12/bi-quyet-khien-saoketv-tro-thanh-trang-xem-bong-da-duoc-ua-chuong-1.jpg"},"inLanguage":"vi","mainEntityOfPage":{"@id":"https://www.automarkhistory.com/#webpage"}}]}</script>
83
84<meta name="google-site-verification" content="4V4Nk-aJkfRfz9xHiiWq9Cj2cICQbA4wuFeycxj_QOs" />
85<!-- /Plugin SEO WordPress Rank Math -->
86
87<link rel='dns-prefetch' href='//cdn.automarkhistory.com' />
88<script type="text/javascript">
89/* <![CDATA[ */
90window._wpemojiSettings = {"baseUrl":"https:\/\/s.w.org\/images\/core\/emoji\/15.1.0\/72x72\/","ext":".png","svgUrl":"https:\/\/s.w.org\/images\/core\/emoji\/15.1.0\/svg\/","svgExt":".svg","source":{"concatemoji":"https:\/\/cdn.automarkhistory.com\/wp-content\/wp-includes\/js\/wp-emoji-release.min.js?ver=6.8.1"}};
91/*! This file is auto-generated */
92!function(i,n){var o,s,e;function c(e){try{var t={supportTests:e,timestamp:(new Date).valueOf()};sessionStorage.setItem(o,JSON.stringify(t))}catch(e){}}function p(e,t,n){e.clearRect(0,0,e.canvas.width,e.canvas.height),e.fillText(t,0,0);var t=new Uint32Array(e.getImageData(0,0,e.canvas.width,e.canvas.height).data),r=(e.clearRect(0,0,e.canvas.width,e.canvas.height),e.fillText(n,0,0),new Uint32Array(e.getImageData(0,0,e.canvas.width,e.canvas.height).data));return t.every(function(e,t){return e===r[t]})}function u(e,t,n){switch(t){case"flag":return n(e,"\ud83c\udff3\ufe0f\u200d\u26a7\ufe0f","\ud83c\udff3\ufe0f\u200b\u26a7\ufe0f")?!1:!n(e,"\ud83c\uddfa\ud83c\uddf3","\ud83c\uddfa\u200b\ud83c\uddf3")&&!n(e,"\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc65\udb40\udc6e\udb40\udc67\udb40\udc7f","\ud83c\udff4\u200b\udb40\udc67\u200b\udb40\udc62\u200b\udb40\udc65\u200b\udb40\udc6e\u200b\udb40\udc67\u200b\udb40\udc7f");case"emoji":return!n(e,"\ud83d\udc26\u200d\ud83d\udd25","\ud83d\udc26\u200b\ud83d\udd25")}return!1}function f(e,t,n){var r="undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?new OffscreenCanvas(300,150):i.createElement("canvas"),a=r.getContext("2d",{willReadFrequently:!0}),o=(a.textBaseline="top",a.font="600 32px Arial",{});return e.forEach(function(e){o[e]=t(a,e,n)}),o}function t(e){var t=i.createElement("script");t.src=e,t.defer=!0,i.head.appendChild(t)}"undefined"!=typeof Promise&&(o="wpEmojiSettingsSupports",s=["flag","emoji"],n.supports={everything:!0,everythingExceptFlag:!0},e=new Promise(function(e){i.addEventListener("DOMContentLoaded",e,{once:!0})}),new Promise(function(t){var n=function(){try{var e=JSON.parse(sessionStorage.getItem(o));if("object"==typeof e&&"number"==typeof e.timestamp&&(new Date).valueOf()<e.timestamp+604800&&"object"==typeof e.supportTests)return e.supportTests}catch(e){}return null}();if(!n){if("undefined"!=typeof Worker&&"undefined"!=typeof OffscreenCanvas&&"undefined"!=typeof URL&&URL.createObjectURL&&"undefined"!=typeof Blob)try{var e="postMessage("+f.toString()+"("+[JSON.stringify(s),u.toString(),p.toString()].join(",")+"));",r=new Blob([e],{type:"text/javascript"}),a=new Worker(URL.createObjectURL(r),{name:"wpTestEmojiSupports"});return void(a.onmessage=function(e){c(n=e.data),a.terminate(),t(n)})}catch(e){}c(n=f(s,u,p))}t(n)}).then(function(e){for(var t in e)n.supports[t]=e[t],n.supports.everything=n.supports.everything&&n.supports[t],"flag"!==t&&(n.supports.everythingExceptFlag=n.supports.everythingExceptFlag&&n.supports[t]);n.supports.everythingExceptFlag=n.supports.everythingExceptFlag&&!n.supports.flag,n.DOMReady=!1,n.readyCallback=function(){n.DOMReady=!0}}).then(function(){return e}).then(function(){var e;n.supports.everything||(n.readyCallback(),(e=n.source||{}).concatemoji?t(e.concatemoji):e.wpemoji&&e.twemoji&&(t(e.twemoji),t(e.wpemoji)))}))}((window,document),window._wpemojiSettings);
93/* ]]> */
94</script>
94
95<style id='wp-emoji-styles-inline-css' type='text/css'>
96
97	img.wp-smiley, img.emoji {
98		display: inline !important;
99		border: none !important;
100		box-shadow: none !important;
101		height: 1em !important;
102		width: 1em !important;
103		margin: 0 0.07em !important;
104		vertical-align: -0.1em !important;
105		background: none !important;
106		padding: 0 !important;
107	}
108</style>
109<link rel='stylesheet' id='wp-block-library-css' href='https://cdn.automarkhistory.com/wp-content/wp-includes/css/dist/block-library/style.min.css?ver=6.8.1' type='text/css' media='all' />
110<style id='classic-theme-styles-inline-css' type='text/css'>
111/*! This file is auto-generated */
112.wp-block-button__link{color:#fff;background-color:#32373c;border-radius:9999px;box-shadow:none;text-decoration:none;padding:calc(.667em + 2px) calc(1.333em + 2px);font-size:1.125em}.wp-block-file__button{background:#32373c;color:#fff;text-decoration:none}
113</style>
114<style id='global-styles-inline-css' type='text/css'>
115:root{--wp--preset--aspect-ratio--square: 1;--wp--preset--aspect-ratio--4-3: 4/3;--wp--preset--aspect-ratio--3-4: 3/4;--wp--preset--aspect-ratio--3-2: 3/2;--wp--preset--aspect-ratio--2-3: 2/3;--wp--preset--aspect-ratio--16-9: 16/9;--wp--preset--aspect-ratio--9-16: 9/16;--wp--preset--color--black: #000000;--wp--preset--color--cyan-bluish-gray: #abb8c3;--wp--preset--color--white: #ffffff;--wp--preset--color--pale-pink: #f78da7;--wp--preset--color--vivid-red: #cf2e2e;--wp--preset--color--luminous-vivid-orange: #ff6900;--wp--preset--color--luminous-vivid-amber: #fcb900;--wp--preset--color--light-green-cyan: #7bdcb5;--wp--preset--color--vivid-green-cyan: #00d084;--wp--preset--color--pale-cyan-blue: #8ed1fc;--wp--preset--color--vivid-cyan-blue: #0693e3;--wp--preset--color--vivid-purple: #9b51e0;--wp--preset--gradient--vivid-cyan-blue-to-vivid-purple: linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%);--wp--preset--gradient--light-green-cyan-to-vivid-green-cyan: linear-gradient(135deg,rgb(122,220,180) 0%,rgb(0,208,130) 100%);--wp--preset--gradient--luminous-vivid-amber-to-luminous-vivid-orange: linear-gradient(135deg,rgba(252,185,0,1) 0%,rgba(255,105,0,1) 100%);--wp--preset--gradient--luminous-vivid-orange-to-vivid-red: linear-gradient(135deg,rgba(255,105,0,1) 0%,rgb(207,46,46) 100%);--wp--preset--gradient--very-light-gray-to-cyan-bluish-gray: linear-gradient(135deg,rgb(238,238,238) 0%,rgb(169,184,195) 100%);
115--wp--preset--gradient--cool-to-warm-spectrum: linear-gradient(135deg,rgb(74,234,220) 0%,rgb(151,120,209) 20%,rgb(207,42,186) 40%,rgb(238,44,130) 60%,rgb(251,105,98) 80%,rgb(254,248,76) 100%);--wp--preset--gradient--blush-light-purple: linear-gradient(135deg,rgb(255,206,236) 0%,rgb(152,150,240) 100%);--wp--preset--gradient--blush-bordeaux: linear-gradient(135deg,rgb(254,205,165) 0%,rgb(254,45,45) 50%,rgb(107,0,62) 100%);--wp--preset--gradient--luminous-dusk: linear-gradient(135deg,rgb(255,203,112) 0%,rgb(199,81,192) 50%,rgb(65,88,208) 100%);--wp--preset--gradient--pale-ocean: linear-gradient(135deg,rgb(255,245,203) 0%,rgb(182,227,212) 50%,rgb(51,167,181) 100%);--wp--preset--gradient--electric-grass: linear-gradient(135deg,rgb(202,248,128) 0%,rgb(113,206,126) 100%);--wp--preset--gradient--midnight: linear-gradient(135deg,rgb(2,3,129) 0%,rgb(40,116,252) 100%);--wp--preset--font-size--small: 13px;--wp--preset--font-size--medium: 20px;--wp--preset--font-size--large: 36px;--wp--preset--font-size--x-large: 42px;--wp--preset--spacing--20: 0.44rem;--wp--preset--spacing--30: 0.67rem;--wp--preset--spacing--40: 1rem;--wp--preset--spacing--50: 1.5rem;--wp--preset--spacing--60: 2.25rem;--wp--preset--spacing--70: 3.38rem;--wp--preset--spacing--80: 5.06rem;--wp--preset--shadow--natural: 6px 6px 9px rgba(0, 0, 0, 0.2);--wp--preset--shadow--deep: 12px 12px 50px rgba(0, 0, 0, 0.4);--wp--preset--shadow--sharp: 6px 6px 0px rgba(0, 0, 0, 0.2);--wp--preset--shadow--outlined: 6px 6px 0px -3px rgba(255, 255, 255, 1), 6px 6px rgba(0, 0, 0, 1);--wp--preset--shadow--crisp: 6px 6px 0px rgba(0, 0, 0, 1);}:where(.is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}body .is-layout-flex{display: flex;}.is-layout-flex{flex-wrap: wrap;align-items: center;}.is-layout-flex > :is(*, div){margin: 0;}body .is-layout-grid{display: grid;}.is-layout-grid > :is(*, div){margin: 0;}:where(.wp-block-columns.is-layout-flex){gap: 2em;}:where(.wp-block-columns.is-layout-grid){gap: 2em;}:where(.wp-block-post-template.is-layout-flex){gap: 1.25em;}:where(.wp-block-post-template.is-layout-grid){gap: 1.25em;}.has-black-color{color: var(--wp--preset--color--black) !important;}.has-cyan-bluish-gray-color{color: var(--wp--preset--color--cyan-bluish-gray) !important;}.has-white-color{color: var(--wp--preset--color--white) !important;}.has-pale-pink-color{color: var(--wp--preset--color--pale-pink) !important;}.has-vivid-red-color{color: var(--wp--preset--color--vivid-red) !important;}.has-luminous-vivid-orange-color{color: var(--wp--preset--color--luminous-vivid-orange) !important;}.has-luminous-vivid-amber-color{color: var(--wp--preset--color--luminous-vivid-amber) !important;}.has-light-green-cyan-color{color: var(--wp--preset--color--light-green-cyan) !important;}.has-vivid-green-cyan-color{color: var(--wp--preset--color--vivid-green-cyan) !important;}.has-pale-cyan-blue-color{color: var(--wp--preset--color--pale-cyan-blue) !important;}.has-vivid-cyan-blue-color{color: var(--wp--preset--color--vivid-cyan-blue) !important;}.has-vivid-purple-color{color: var(--wp--preset--color--vivid-purple) !important;}.has-black-background-color{background-color: var(--wp--preset--color--black) !important;}.has-cyan-bluish-gray-background-color{background-color: var(--wp--preset--color--cyan-bluish-gray) !important;}.has-white-background-color{background-color: var(--wp--preset--color--white) !important;}.has-pale-pink-background-color{background-color: var(--wp--preset--color--pale-pink) !important;}.has-vivid-red-background-color{background-color: var(--wp--preset--color--vivid-red) !important;}.has-luminous-vivid-orange-background-color{background-color: var(--wp--preset--color--luminous-vivid-orange) !important;}.has-luminous-vivid-amber-background-color{background-color: var(--wp--preset--color--luminous-vivid-amber) !important;}.has-light-green-cyan-background-color{background-color: var(--wp--preset--color--light-green-cyan) !important;}.has-vivid-green-cyan-background-color{background-color: var(--wp--preset--color--vivid-green-cyan) !important;}.has-pale-cyan-blue-background-color{background-color: var(--wp--preset--color--pale-cyan-blue) !important;}.has-vivid-cyan-blue-background-color{background-color: var(--wp--preset--color--vivid-cyan-blue) !important;}.has-vivid-purple-background-color{background-color: var(--wp--preset--color--vivid-purple) !important;}.has-black-border-color{border-color: var(--wp--preset--color--black) !important;}.has-cyan-bluish-gray-border-color{border-color: var(--wp--preset--color--cyan-bluish-gray) !important;}.has-white-border-color{border-color: var(--wp--preset--color--white) !important;}.has-pale-pink-border-color{border-color: var(--wp--preset--color--pale-pink) !important;}.has-vivid-red-border-color{border-color: var(--wp--preset--color--vivid-red) !important;}.has-luminous-vivid-orange-border-color{border-color: var(--wp--preset--color--luminous-vivid-orange) !important;}.has-luminous-vivid-amber-border-color{border-color: var(--wp--preset--color--luminous-vivid-amber) !important;}.has-light-green-cyan-border-color{border-color: var(--wp--preset--color--light-green-cyan) !important;}.has-vivid-green-cyan-border-color{border-color: var(--wp--preset--color--vivid-green-cyan) !important;}.has-pale-cyan-blue-border-color{border-color: var(--wp--preset--color--pale-cyan-blue) !important;}.has-vivid-cyan-blue-border-color{border-color: var(--wp--preset--color--vivid-cyan-blue) !important;}.has-vivid-purple-border-color{border-color: var(--wp--preset--color--vivid-purple) !important;}.has-vivid-cyan-blue-to-vivid-purple-gradient-background{background: var(--wp--preset--gradient--vivid-cyan-blue-to-vivid-purple) !important;}.has-light-green-cyan-to-vivid-green-cyan-gradient-background{background: var(--wp--preset--gradient--light-green-cyan-to-vivid-green-cyan) !important;}.has-luminous-vivid-amber-to-luminous-vivid-orange-gradient-background{background: var(--wp--preset--gradient--luminous-vivid-amber-to-luminous-vivid-orange) !important;}.has-luminous-vivid-orange-to-vivid-red-gradient-background{background: var(--wp--preset--gradient--luminous-vivid-orange-to-vivid-red) !important;}
115.has-very-light-gray-to-cyan-bluish-gray-gradient-background{background: var(--wp--preset--gradient--very-light-gray-to-cyan-bluish-gray) !important;}.has-cool-to-warm-spectrum-gradient-background{background: var(--wp--preset--gradient--cool-to-warm-spectrum) !important;}.has-blush-light-purple-gradient-background{background: var(--wp--preset--gradient--blush-light-purple) !important;}.has-blush-bordeaux-gradient-background{background: var(--wp--preset--gradient--blush-bordeaux) !important;}.has-luminous-dusk-gradient-background{background: var(--wp--preset--gradient--luminous-dusk) !important;}.has-pale-ocean-gradient-background{background: var(--wp--preset--gradient--pale-ocean) !important;}.has-electric-grass-gradient-background{background: var(--wp--preset--gradient--electric-grass) !important;}.has-midnight-gradient-background{background: var(--wp--preset--gradient--midnight) !important;}.has-small-font-size{font-size: var(--wp--preset--font-size--small) !important;}.has-medium-font-size{font-size: var(--wp--preset--font-size--medium) !important;}.has-large-font-size{font-size: var(--wp--preset--font-size--large) !important;}.has-x-large-font-size{font-size: var(--wp--preset--font-size--x-large) !important;}
116:where(.wp-block-post-template.is-layout-flex){gap: 1.25em;}:where(.wp-block-post-template.is-layout-grid){gap: 1.25em;}
117:where(.wp-block-columns.is-layout-flex){gap: 2em;}:where(.wp-block-columns.is-layout-grid){gap: 2em;}
118:root :where(.wp-block-pullquote){font-size: 1.5em;line-height: 1.6;}
119</style>
120<link rel='stylesheet' id='main-style-css' href='https://cdn.automarkhistory.com/wp-content/themes/cakhiatv/style.css?ver=1770998152' type='text/css' media='all' />
121<link rel="https://api.w.org/" href="https://www.automarkhistory.com/wp-json/" /><link rel="alternate" title="JSON" type="application/json" href="https://www.automarkhistory.com/wp-json/wp/v2/pages/1040" /><link rel="EditURI" type="application/rsd+xml" title="RSD" href="https://www.automarkhistory.com/xmlrpc.php?rsd" />
122<meta name="generator" content="WordPress 6.8.1" />
123<link rel='shortlink' href='https://www.automarkhistory.com/' />
124<link rel="alternate" title="oNhúng (JSON)" type="application/json+oembed" href="https://www.automarkhistory.com/wp-json/oembed/1.0/embed?url=https%3A%2F%2Fwww.automarkhistory.com%2F" />
125<link rel="alternate" title="oNhúng (XML)" type="text/xml+oembed" href="https://www.automarkhistory.com/wp-json/oembed/1.0/embed?url=https%3A%2F%2Fwww.automarkhistory.com%2F&#038;format=xml" />
126    <style>
127   .chat-message .cw-message-content{
128        color: #fff;
129    }
130        @media (min-width: 1024px) {
131            h1 {
132                font-size: 1.5em !important;
133            }
134        }
135
136        .match-teams-score {
137            display: flex !important;
138        }
139
140        @media (max-width: 767px) {
141            .xgplayer .xg-inner-controls {
142                height: 60px !important;
143            }
144            .header .logo img{
145                height: 35px;
146            }
147        }
148
149        @media (min-width: 481px) and (max-width: 767px) {
150            div#chat_messages {
151                max-height: 60vh !important;
152            }
153        }
154    </style>
155    <style>
156            .match-section {
157                min-height: 100%;
158            }
159            
160            .match-card__status {
161                position: absolute;
162                top: 13%;
163                left: 50%;
164                transform: translate(-50%, -50%);
165            }
166            
167            .match-card__stats-content {
168                background: none !important;
169                box-shadow: none !important
170            }
171            
172            
173            
174            @media (max-width: 480px) {
175                .team__logo {
176                    width: 40px !important;
177                    height: 40px !important;
178                }
179                .match-card__league {
180                    max-width: 100px;
181                }
182                
183                .match-card__time {
184                    max-width: 100px;
185                }
186                
187                .match-card__status {
188                    max-width: 120px;
189                    order: 1 !important;
190                    font-size: 12px
191                }
192                
193                .streaming {
194                    padding: 4px;
195                }
196                
197                .btn-view-truc-tiep {
198                    padding: 8px 4px !important;
199                    font-size: 12px;
200                }
201                .match-card__stats-content {
202                    display: block !important;
203                }
204                
205                .match-card__stats {
206                    display: block !important
207                }
208            }
209            
210            @media (min-width: 768px) and (max-width: 1024px) {
211                .match-card__status {
212                    position: absolute;
213                    top: 13%;
214                    left: 50%;
215                    transform: translate(-50%, -50%);
216                }
217                
218                .match-card__league {
219                    max-width: 110px;
220                }
221            }
222        </style><link rel="icon" href="https://cdn.automarkhistory.com/wp-content/uploads/2025/12/cropped-6161200216581803284-removebg-preview-32x32.png" sizes="32x32" />
223<link rel="icon" href="https://cdn.automarkhistory.com/wp-content/uploads/2025/12/cropped-6161200216581803284-removebg-preview-192x192.png" sizes="192x192" />
224<link rel="apple-touch-icon" href="https://cdn.automarkhistory.com/wp-content/uploads/2025/12/cropped-6161200216581803284-removebg-preview-180x180.png" />
225<meta name="msapplication-TileImage" content="https://cdn.automarkhistory.com/wp-content/uploads/2025/12/cropped-6161200216581803284-removebg-preview-270x270.png" />
226  
227
228</head>
229
230<body>
231  <!-- Header -->
232<header class="header">
233    <div class="container">
234      <div class="header__inner">
235        <a href="/" class="logo">
236          <img src="https://cdn.automarkhistory.com/wp-content/themes/cakhiatv/assets/images/saoketvlogo.png" alt="Menu"  style="height:90px">
237        </a>
238        <div style="display: flex; align-items: center">
239          <nav class="nav">
240            <button class="nav__toggle">
241              <img src="https://cdn.automarkhistory.com/wp-content/themes/cakhiatv/assets/images/hamburger.svg" alt="Menu" />
242            </button>
243
244            <ul class="nav__menu">
245              <button class="nav__close" aria-label="Close menu"></button>
246              <li class="nav__item"><a href="/" class=" active">Saoke TV</a></li><li class="nav__item"><a href="https://www.automarkhistory.com/bang-xep-hang/" class="">Bảng xếp hạng</a></li><li class="nav__item"><a href="https://www.automarkhistory.com/ket-qua-bong-da/" class="">Kết quả bóng đá</a></li><li class="nav__item"><a href="https://www.automarkhistory.com/lich-thi-dau/" class="">Lịch thi đấu</a></li><li class="nav__item"><a href="https://www.automarkhistory.com/nhan-dinh/" class="">Nhận định bóng đá</a></li><li class="nav__item"><a href="https://www.automarkhistory.com/soi-keo/" class="">Soi kèo bóng đá</a></li><li class="nav__item"><a href="https://www.automarkhistory.com/tin-tuc/" class="">Tin tức</a></li>            </ul>
247          </nav>
248          <div class="header__buttons">
249            <a href="https://vsbetz75.com/login/" target="_blank"  class="btn btn--secondary header-button" rel="nofollow">
250              <span class="header-text">CƯỢC VSBET</span>
251            </a>
252             <a href="https://vsbetz75.com/registered" class="btn btn--secondary header-button2" rel="nofollow">
253              <span class="header-text">ĐĂNG KÝ</span>
254            </a>
255          
256          </div>
257
258        </div>
259
260
261
262      </div>
263    </div>
264  </header>
265 
266   <!-- Main Content -->
267     <!-- Main Content -->
268     <main style="padding-top: 1px">
269      <section class="ads">
270        <div class="container">
271           <a href="<br />
272<b>Warning</b>:  file_get_contents(): php_network_getaddresses: getaddrinfo for xoilackvb.cc failed: Name or service not known in <b>/www/sites/automarkhistory.com/wp-content/themes/cakhiatv/front-page.php</b> on line <b>12</b><br />
273<br />
274<b>Warning</b>:  file_get_contents(https://xoilackvb.cc/link.php): Failed to open stream: php_network_getaddresses: getaddrinfo for xoilackvb.cc failed: Name or service not known in <b>/www/sites/automarkhistory.com/wp-content/themes/cakhiatv/front-page.php</b> on line <b>12</b><br />
275" target="_blank" rel="nofollow"><img style="display: none" src="<br />
276<b>Warning</b>:  file_get_contents(): php_network_getaddresses: getaddrinfo for xoilackvb.cc failed: Name or service not known in <b>/www/sites/automarkhistory.com/wp-content/themes/cakhiatv/front-page.php</b> on line <b>12</b><br />
277<br />
278<b>Warning</b>:  file_get_contents(https://xoilackvb.cc/banner.php): Failed to open stream: php_network_getaddresses: getaddrinfo for xoilackvb.cc failed: Name or service not known in <b>/www/sites/automarkhistory.com/wp-content/themes/cakhiatv/front-page.php</b> on line <b>12</b><br />
279" /></a>
280        </div>
281      </section>
282      <!-- Hero Section -->
283      <section class="hero">
284        <div class="container">
285          <div class="hero__content">
286            <h1 class="text-uppercase">
287          <p>Saoketv &#8211; Trang xem trực tiếp bóng đá rõ nét, ổn định 24/7</p>
288            </h1>
289          </div>
290        </div>
291      </section>
292
293      <!-- Sports Filter -->
294      <section class="sports-filter" >
295        <div class="container">
296          <div class="sports-filter__inner" style="display: none">
297            <!-- Group 1: Sports Categories -->
298            <!--<div class="sports-filter__group sports-categories">
299            <button
300                class="sports-filter__button"
301                data-sport="all"
302              >
303                <div class="sports-filter__button-icon">
304                  <img
305                    src="https://cdn.automarkhistory.com/wp-content/themes/cakhiatv/assets/images/icons/football.png"
306                    alt="Tất Cả"
307                  />
308                </div>
309                <div class="sports-filter__button-text">Tất Cả</div>
310                <div class="sports-filter__button-count" id="count-all-type"></div>
311              </button>
312
313              <button
314                class="sports-filter__button"
315                data-sport="football"
316              >
317                <div class="sports-filter__button-icon">
318                  <img
319                    src="https://cdn.automarkhistory.com/wp-content/themes/cakhiatv/assets/images/icons/football.png"
320                    alt="Football"
321                  />
322                </div>
323                <div class="sports-filter__button-text">Bóng đá</div>
324                <div class="sports-filter__button-count" id="count-football"></div>
325              </button>
326
327              <button class="sports-filter__button" data-sport="basketball">
328                <div class="sports-filter__button-icon">
329                  <img
330                    src="https://cdn.automarkhistory.com/wp-content/themes/cakhiatv/assets/images/icons/basketball.png"
331                    alt="Basketball"
332                  />
333                </div>
334                <div class="sports-filter__button-text">Bóng rổ</div>
335                <div class="sports-filter__button-count" id="count-basketball"></div>
336              </button>
337
338             <!-- <button class="sports-filter__button" data-sport="tennis">
339                <div class="sports-filter__button-icon">
340                  <img src="https://cdn.automarkhistory.com/wp-content/themes/cakhiatv/assets/images/icons/tennis.png" alt="Tennis" />
341                </div>
342                <div class="sports-filter__button-text">Tennis</div>
343                <div class="sports-filter__button-count" id="count-tennis"></div>
344              </button> -->
345
346              <!--<button class="sports-filter__button" data-sport="volleyball">
347                <div class="sports-filter__button-icon">
348                  <img
349                    src="https://cdn.automarkhistory.com/wp-content/themes/cakhiatv/assets/images/icons/volleyball.png"
350                    alt="Volleyball"
351                  />
352                </div>
353                <div class="sports-filter__button-text">Bóng chuyền</div>
354                <div class="sports-filter__button-count" id="count-volleyball"></div>
355              </button> -->
356
357              <div class="livescore-switch">
358                <label class="switch">
359                  <input type="checkbox" id="livescoreToggle" />
360                  <span class="slider"></span>
361                </label>
362                <span class="livescore-label">Livescore</span>
363              </div>
364            </div>
365
366            <!-- Divider -->
367            <div class="sports-filter__divider"></div>
368
369            <!-- Group 2: Match Filters -->
370            <div class="sports-filter__group match-filters">
371            <button class="sports-filter__button_child active" data-filter="child_all">
372                <div class="sports-filter__button-icon">
373                  <img src="https://cdn.automarkhistory.com/wp-content/themes/cakhiatv/assets/images/icons/all.png" alt="All" />
374                </div>
375                <div class="sports-filter__button-text">Tất cả</div>
376                <div class="sports-filter__button-count" id="count-all-type"></div>
377              </button>
378
379              <button class="sports-filter__button_child live" data-filter="live">
380                <div class="sports-filter__button-icon">
381                  <img src="https://cdn.automarkhistory.com/wp-content/themes/cakhiatv/assets/images/icons/live.png" alt="Live" />
382                </div>
383                <div class="sports-filter__button-text">Đang Live</div>
384                <div class="sports-filter__button-count" id="count-live"></div>
385              </button>
386
387              <!--<button class="sports-filter__button_child" data-filter="hot">
388                <div class="sports-filter__button-icon">
389                  <img src="https://cdn.automarkhistory.com/wp-content/themes/cakhiatv/assets/images/icons/hot.png" alt="Hot" />
390                </div>
391                <div class="sports-filter__button-text">Trận HOT</div>
392                <div class="sports-filter__button-count" id="count-hot">48</div>
393              </button>-->
394
395              <!--<button class="sports-filter__button_child" data-filter="date" data-value="2026-09-27">
396                <div class="sports-filter__button-icon">
397                  <img src="https://cdn.automarkhistory.com/wp-content/themes/cakhiatv/assets/images/icons/calendar.png" alt="Today" />
398                </div>
399                <div class="sports-filter__button-text">Hôm Nay</div>
400                <div class="sports-filter__button-count" id="count-today"></div>
401              </button>-->
402
403              <!--<button class="sports-filter__button_child" data-filter="date" data-value="2026-09-28">
404                <div class="sports-filter__button-icon">
405                  <img
406                    src="https://cdn.automarkhistory.com/wp-content/themes/cakhiatv/assets/images/icons/calendar.png"
407                    alt="Tomorrow"
408                  />
409                </div>
410                <div class="sports-filter__button-text">Ngày Mai</div>
411                <div class="sports-filter__button-count" id="count-tomorrow"></div>
412              </button>-->           
413            <!--  
414             <button class="sports-filter__button_child" data-filter="no_blv">
415                <div class="sports-filter__button-text">Live không BLV</div>
416                <div class="sports-filter__button-count" id="noblv-live">0</div>
417              </button>
418              -->
419            </div>
420          </div>
421        </div>
422      </section>
423
424      <!-- Featured Matches -->
425      <section class="featured-matches" style="">
426        <div class="container">
427        <div class="match-section">
428            <div id="match-list" class="matches">
429            </div>
430          </div>
431
432          <!--<div
433            style="
434              display: flex;
435              justify-content: center;
436              margin-top: 1rem;
437              margin-bottom: 1rem;
438            "
439          >
440            <a href="#" class="btn btn--readmore">
441              <span>Xem thêm lịch trực tiếp -></span>
442            </a>
443          </div>-->
444        </div>
445      </section>
446
447      <!-- Content Navigation Section -->
448      <section class="content-nav">
449  <div class="container">
450    <div class="content-nav__container" style="max-height:800px !important">
451      <div class="content-nav__lists">
452        <div class="content-nav__list">
453          <!-- Nếu bạn vẫn muốn giữ Mục lục này thủ công, thì để lại -->
454          <p style="font-weight: bold; font-size: 120%">Mục Lục</p>
455          <!-- Hoặc có thể xoá toàn bộ <ul>
455 này nếu muốn Gutenberg xử lý luôn -->
456
457          <div class="content-nav__divider"></div>
458
459          <div class="content-nav__text">
460            <p><a href="/">Saoketv</a> là kênh TTBD quen thuộc của những tín đồ bóng đá, nơi bạn có thể theo dõi mọi trận cầu đỉnh cao hoàn toàn miễn phí. Có thể theo dõi mọi giải đấu lớn nhỏ  từ Ngoại hạng Anh đến V-League với đường truyền ổn định. Không chỉ xem bóng đá, kênh còn mang đến lịch thi đấu, tỷ số trực tiếp và những thông tin nóng hổi mỗi ngày cho người hâm mộ.</p>
461<h2>Lý do mọi người nên xem bd truc tuyen trên Saoketv</h2>
462<div id="attachment_1310" style="width: 810px" class="wp-caption aligncenter"><img fetchpriority="high" decoding="async" aria-describedby="caption-attachment-1310" class="size-full wp-image-1310" src="https://cdn.enjoysmallthings.com/wp-content/uploads/2025/12/bi-quyet-khien-saoketv-thanh-web-xem-bong-da-uy-tin-5.jpg" alt="bi quyet khien saoketv thanh web xem bong da uy tin 5" width="800" height="400" title="Saoketv - Trang xem trực tiếp bóng đá rõ nét, ổn định 24/7 1" srcset="https://cdn.automarkhistory.com/wp-content/uploads/2025/12/bi-quyet-khien-saoketv-thanh-web-xem-bong-da-uy-tin-5.jpg 800w, https://cdn.automarkhistory.com/wp-content/uploads/2025/12/bi-quyet-khien-saoketv-thanh-web-xem-bong-da-uy-tin-5-300x150.jpg 300w, https://cdn.automarkhistory.com/wp-content/uploads/2025/12/bi-quyet-khien-saoketv-thanh-web-xem-bong-da-uy-tin-5-768x384.jpg 768w" sizes="(max-width: 800px) 100vw, 800px" /><p id="caption-attachment-1310" class="wp-caption-text">Bí quyết khiến Saoketv trở thành trang xem bóng đá được ưa chuộng</p></div>
463<p>Saoketv là trang xem bóng đá nổi bật, mang đến cho người hâm mộ những trải nghiệm thể thao hoàn toàn mới mẻ và tiện lợi. Chỉ với một thiết bị có Internet, bạn có thể tận hưởng trận cầu đỉnh cao ở bất kỳ nơi đâu.</p>
464<h3>Thưởng thức bóng đá liền mạch, không bị ngắt quãng</h3>
465<p>Trang web giúp bạn xem trực tiếp mọi trận đấu lớn nhỏ trong và ngoài nước. Dù là các giải hàng đầu châu Âu hay những trận cầu Việt Nam, bạn đều có thể theo dõi dễ dàng. Mọi khung giờ, mọi thiết bị, chỉ cần truy cập là có thể xem bd ngay. Không còn bỏ lỡ những phút giây kịch tính vì giới hạn về thời gian hay địa điểm.</p>
466<h3>Độ nét cao, tốc độ phát nhanh chóng</h3>
467<p>Một trong những ưu điểm nổi bật của trang là chất lượng hình ảnh siêu mượt. Nhờ hệ thống máy chủ tối ưu, video luôn sắc nét, không giật lag hay bị đứng hình. Mỗi pha chuyền bóng, cú sút hay tình huống gay cấn đều được tái hiện chân thực. Trải nghiệm xem ttbd của bạn luôn mượt mà và sống động như đang ở sân vận động.</p>
468<h3>Không cần trả phí để tận hưởng</h3>
469<p>Saoketv mang lại cho người dùng sự tự do tuyệt đối khi thưởng thức bóng đá mà không mất tiền. Không yêu cầu đăng ký, không thu phí ẩn, chỉ cần truy cập là có thể xem trực tiếp bóng đá ngay. Người hâm mộ có thể tiết kiệm chi phí mà vẫn xem được những trận cầu đỉnh cao. Đây là lựa chọn tối ưu cho mọi tầng lớp yêu bóng đá.</p>
470<h3>Cập nhật liên tục những giải bóng hot nhất hành tinh</h3>
471<p>Từ Ngoại Hạng Anh, Bundesliga đến Champions League hay EURO, tất cả đều có mặt trên Saoketv. Bạn không cần phải tìm kiếm rời rạc trên nhiều trang web bongdatructiep khác nhau. Hệ thống liên tục cập nhật để đảm bảo mọi giải đấu hot nhất đều được phát sóng. Sự đa dạng này khiến trang web trở thành trung tâm của người mê túc cầu.</p>
472<h3>Bình luận sinh động, cảm xúc chân thật</h3>
473<p>Các trận đấu trên Saoketv được lồng tiếng và bình luận tiếng Việt chuyên nghiệp. Giọng bình luận viên mang đến sự hào hứng, giúp trận đấu thêm phần cuốn hút. Họ không chỉ tường thuật mà còn phân tích chiến thuật và tình huống hay. Nhờ đó, người xem cảm thấy gần gũi và dễ hòa mình vào không khí trận đấu.</p>
474<h3>Xem mượt trên mọi thiết bị</h3>
475<p>Saoketv tương thích hoàn toàn với điện thoại, máy tính bảng, laptop và smart TV. Dù bạn ở nhà, đi làm hay đang du lịch, chỉ cần có mạng là có thể xemtructiepbongda ngay. Hệ thống tự động điều chỉnh chất lượng phù hợp với tốc độ Internet. Người dùng luôn có trải nghiệm ổn định và tiện lợi dù ở bất kỳ đâu.</p>
476<h3>
476Ít quảng cáo, không bị gián đoạn</h3>
477<p>Không gì khó chịu hơn khi đang xem trận đấu mà bị quảng cáo xen ngang. Saoketv hiểu điều đó và luôn giữ cho màn hình xem của bạn thông suốt. Tần suất quảng cáo được giảm tối đa để không làm mất cảm xúc. Bạn được tận hưởng trận đấu trọn vẹn từ đầu đến cuối mà không bị làm phiền.</p>
478<h2>Trang tructiepbongda Saoketv có bản quyền của tất cả giải đấu</h2>
479<div id="attachment_1315" style="width: 810px" class="wp-caption aligncenter"><img decoding="async" aria-describedby="caption-attachment-1315" class="size-full wp-image-1315" src="https://cdn.enjoysmallthings.com/wp-content/uploads/2025/12/saoketv-noi-quy-tu-cac-giai-bong-da-hang-dau-the-gioi-1-7.jpg" alt="saoketv noi quy tu cac giai bong da hang dau the gioi 1 7" width="800" height="400" title="Saoketv - Trang xem trực tiếp bóng đá rõ nét, ổn định 24/7 2" srcset="https://cdn.automarkhistory.com/wp-content/uploads/2025/12/saoketv-noi-quy-tu-cac-giai-bong-da-hang-dau-the-gioi-1-7.jpg 800w, https://cdn.automarkhistory.com/wp-content/uploads/2025/12/saoketv-noi-quy-tu-cac-giai-bong-da-hang-dau-the-gioi-1-7-300x150.jpg 300w, https://cdn.automarkhistory.com/wp-content/uploads/2025/12/saoketv-noi-quy-tu-cac-giai-bong-da-hang-dau-the-gioi-1-7-768x384.jpg 768w" sizes="(max-width: 800px) 100vw, 800px" /><p id="caption-attachment-1315" class="wp-caption-text">Saoketv nơi quy tụ các giải bóng đá hàng đầu thế giới</p></div>
480<p>Trên Saoketv, khán giả có thể xembd live nhiều giải đấu đẳng cấp quốc tế cũng như các giải trong nước được cập nhật liên tục. Dưới đây là một số giải đấu hấp dẫn đang được phát sóng thường xuyên.</p>
481<table>
482<tbody>
483<tr>
484<td>Các giải đấu</td>
485<td>Các đội nổi bật</td>
486<td>Các chức năng trực tiếp</td>
487</tr>
488<tr>
489<td>Ngoại Hạng Anh – Giải bóng đá sôi động, kịch tính hàng đầu châu Âu</td>
490<td>Manchester United, Liverpool, Chelsea, Arsenal</td>
491<td>Saoketv tường thuật trực tiếp Premier League, cập nhật từng bàn thắng và pha bóng quan trọng. Người hâm mộ có thể xem bong da mọi lúc, mọi nơi nhờ đường truyền mượt mà. Tính năng trực tiếp giúp trải nghiệm trận đấu sống động và chân thực.</td>
492</tr>
493<tr>
494<td>Xem trực tiếp bóng đá giải Champions League</td>
495<td>Real Madrid, Manchester City, Bayern Munich, PSG</td>
496<td>Mọi trận Champions League đều được Saoketv phát trực tiếp ngay khi diễn ra. Người xem có thể tận hưởng từng bàn thắng và pha bóng gay cấn mà không bị gián đoạn. Tính năng truc tiep bong da đảm bảo cảm xúc trận đấu được truyền tải trọn vẹn. Trang web là lựa chọn hàng đầu cho fan bóng đá châu Âu.</td>
497</tr>
498<tr>
499<td>Europa League – Sân chơi đẳng cấp thứ hai châu Âu</td>
500<td>Sevilla, Arsenal, AS Roma, Bayer Leverkusen</td>
501<td>Saoketv tường thuật trực tiếp Europa League với đường truyền mượt mà, ổn định. Mọi diễn biến trên sân đều được cập nhật tức thì. Tính năng ttbd mang lại trải nghiệm bóng đá chân thực. Người xem có thể theo dõi mọi trận đấu một cách thuận tiện.</td>
502</tr>
503<tr>
504<td>La Liga – Nơi hội tụ tinh hoa bóng đá mang đậm bản sắc Tây Ban Nha</td>
505<td>Barcelona, Real Madrid, Atletico Madrid, Sevilla</td>
506<td>Tất cả các trận La Liga đều được Saoketv phát trực tiếp chất lượng cao. Mọi bàn thắng và tình huống gay cấn đều hiển thị rõ nét. Tính năng bóng đá live giúp người xem không bỏ lỡ khoảnh khắc quan trọng. Saoketv mang đến trải nghiệm bóng đá trọn vẹn, gần gũi với khán giả.</td>
507</tr>
508<tr>
509<td>Serie A – Nét tinh tế và chiến thuật bậc thầy của bóng đá Ý</td>
510<td>Juventus, AC Milan, Inter Milan, Napoli</td>
511<td>Saoketv cung cấp trực tiếp Serie A với tốc độ ổn định và hình ảnh sắc nét. Người xem có thể theo sát từng chiến thuật và pha bóng quan trọng. Tính năng trực tiếp tạo cảm giác như đang theo dõi trận đấu tại sân vận động. Đây là điểm đến lý tưởng cho fan bóng đá Ý.</td>
512</tr>
513<tr>
514<td>V-League – Sức hút đến từ sân cỏ Việt Nam</td>
515<td>Hà Nội FC, HAGL, Viettel, Bình Dương</td>
516<td>Người hâm mộ bóng đá Việt Nam có thể xem trực tiếp V-League ngay trên Saoketv. Tất cả các trận đấu trong nước đều được cập nhật chất lượng cao. Xem bd truc tiep giúp khán giả hòa mình vào không khí sôi động. Saoketv là địa chỉ tin cậy cho fan bóng đá nội địa.</td>
517</tr>
518<tr>
519<td>Bundesliga – Giải đấu tầm cỡ thế giới, thu hút hàng nghìn khán giả</td>
520<td>Bayern Munich, Borussia Dortmund, RB Leipzig, Bayer Leverkusen</td>
521<td>Người hâm mộ Bundesliga có thể xem trực tiếp các trận đấu trên Saoketv với chất lượng cao. Mỗi bàn thắng và p
521ha xử lý kỹ thuật được cập nhật nhanh chóng. Tính năng trực tiếp mang lại trải nghiệm chân thực và sống động. Saoketv kết nối người hâm mộ với giải đấu Đức hiệu quả.</td>
522</tr>
523<tr>
524<td>AFC Champions League</td>
525<td>Al Hilal, Urawa Reds, Pohang Steelers, Jeonbuk Hyundai Motors</td>
526<td>Saoketv tường thuật trực tiếp AFC Champions League, giúp người xem theo dõi các câu lạc bộ châu Á kịch tính. Mỗi bàn thắng và pha xử lý đều được phát sóng ngay lập tức. Tính năng trực tiếp mang đến trải nghiệm sống động và chân thực. Saoketv là cầu nối niềm đam mê bóng đá châu Á cho khán giả Việt.</td>
527</tr>
528</tbody>
529</table>
530<p>&nbsp;</p>
531<h2>Tổng hợp các BLV chuyên nghiệp trên trực tiếp bóng đá Saoketv</h2>
532<div id="attachment_1312" style="width: 810px" class="wp-caption aligncenter"><img decoding="async" aria-describedby="caption-attachment-1312" class="size-full wp-image-1312" src="https://cdn.enjoysmallthings.com/wp-content/uploads/2025/12/gap-go-doi-ngu-blv-tai-nang-dong-hanh-cung-saoketv-7.jpg" alt="gap go doi ngu blv tai nang dong hanh cung saoketv 7" width="800" height="400" title="Saoketv - Trang xem trực tiếp bóng đá rõ nét, ổn định 24/7 3" srcset="https://cdn.automarkhistory.com/wp-content/uploads/2025/12/gap-go-doi-ngu-blv-tai-nang-dong-hanh-cung-saoketv-7.jpg 800w, https://cdn.automarkhistory.com/wp-content/uploads/2025/12/gap-go-doi-ngu-blv-tai-nang-dong-hanh-cung-saoketv-7-300x150.jpg 300w, https://cdn.automarkhistory.com/wp-content/uploads/2025/12/gap-go-doi-ngu-blv-tai-nang-dong-hanh-cung-saoketv-7-768x384.jpg 768w" sizes="(max-width: 800px) 100vw, 800px" /><p id="caption-attachment-1312" class="wp-caption-text">Gặp gỡ đội ngũ BLV tài năng đồng hành cùng Saoketv</p></div>
533<p>Một trận bóng đá hấp dẫn không chỉ đến từ những pha ghi bàn đẹp mắt, mà còn nhờ giọng bình luận truyền cảm của các BLV. Trên Saoketv, đội ngũ bình luận viên chuyên nghiệp chính là điểm nhấn giúp mỗi buổi xem bong da trở nên sống động và cuốn hút hơn bao giờ hết.</p>
534<h3>BLV Minh Đức – Giọng nói của nhiệt huyết</h3>
535<p>BLV Minh Đức là gương mặt quen thuộc với khán giả Saoketv. Anh sở hữu giọng nói mạnh mẽ, truyền cảm và phong cách bình luận đầy năng lượng. Mỗi pha bóng được anh miêu tả đều khiến người nghe cảm thấy như đang sống trong không khí sân cỏ thật sự. Minh Đức nổi bật với khả năng làm chủ cảm xúc, tạo nên bầu không khí sôi động và hào hứng.</p>
536<h3>BLV Hoàng Nam – Chuyên gia phân tích chiến thuật</h3>
537<p>Không chỉ tường thuật, Hoàng Nam còn là người “giải mã” từng đường chuyền, từng đội hình thi đấu. Anh có kiến thức sâu rộng về chiến thuật, mang đến cho người xem góc nhìn đa chiều. Khi nghe anh bình luận, khán giả không chỉ được giải trí mà còn học hỏi thêm về chuyên môn bóng đá. Sự logic và tinh tế là điểm mạnh khiến Hoàng Nam được yêu mến.</p>
538<h3>BLV Quang Anh – Cảm xúc chân thực trong từng câu nói</h3>
539<p>Quang Anh là cái tên quen thuộc với những ai yêu thích sự tự nhiên, gần gũi. Anh không quá “kỹ thuật” trong lời nói, mà chú trọng đến cảm xúc chân thật của người xem bd tt. Giọng nói trầm ấm và cách thể hiện nhẹ nhàng giúp người nghe cảm thấy thoải mái. Với Quang Anh, mỗi trận đấu là một câu chuyện, một hành trình của cảm xúc.</p>
540<h3>BLV Hải Sơn – Người truyền lửa của Saoketv</h3>
541<p>Hải Sơn là một trong những BLV được đánh giá cao nhờ khả năng khuấy động không khí. Anh luôn mang đến tinh thần máu lửa, sôi nổi trong từng phút tường thuật. Phong cách bình luận mạnh mẽ, pha chút hài hước khiến khán giả vô cùng thích thú. Với Hải Sơn, trận đấu nào cũng trở thành một lễ hội bóng đá đích thực.</p>
542<h3>BLV Việt Dũng – Phân tích sắc bén, kiến thức vững vàng</h3>
543<p>Việt Dũng là người có nhiều năm kinh nghiệm trong lĩnh vực bình luận thể thao. Anh am hiểu bóng đá châu Âu, đặc biệt là Ngoại Hạng Anh và Champions League. Những phân tích của anh luôn chính xác, đi sâu vào bản chất chiến thuật. Nhờ vậy, người xem bd live không chỉ xem mà còn hiểu sâu hơn về lối chơi của từng đội bóng.</p>
544<h2>Hướng dẫn truy cập link chính thức Saoketv an toàn</h2>
545<div id="attachment_1317" style="width: 810px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-1317" class="size-full wp-image-1317" src="https://cdn.enjoysmallthings.com/wp-content/uploads/2025/12/tim-link-xem-bong-da-saoketv-chuan-khong-bi-ch
545an-5.jpg" alt="tim link xem bong da saoketv chuan khong bi chan 5" width="800" height="400" title="Saoketv - Trang xem trực tiếp bóng đá rõ nét, ổn định 24/7 4" srcset="https://cdn.automarkhistory.com/wp-content/uploads/2025/12/tim-link-xem-bong-da-saoketv-chuan-khong-bi-chan-5.jpg 800w, https://cdn.automarkhistory.com/wp-content/uploads/2025/12/tim-link-xem-bong-da-saoketv-chuan-khong-bi-chan-5-300x150.jpg 300w, https://cdn.automarkhistory.com/wp-content/uploads/2025/12/tim-link-xem-bong-da-saoketv-chuan-khong-bi-chan-5-768x384.jpg 768w" sizes="auto, (max-width: 800px) 100vw, 800px" /><p id="caption-attachment-1317" class="wp-caption-text">Cách tìm link xem bóng đá Saoketv chuẩn không bị chặn</p></div>
546<p>Việc truy cập các trang web xem bóng đá trực tuyến cần được thực hiện cẩn trọng để tránh rủi ro. Nhiều đường link xem bóng đá trực tiếp giả mạo, chứa mã độc hoặc quảng cáo độc hại có thể khiến người xem gặp nguy hiểm.</p>
547<ul>
548<li style="font-weight: 400;" aria-level="1"><strong>Xác định đúng địa chỉ trang Saoketv chính thức</strong>: Trước tiên, người xem cần kiểm tra kỹ đường dẫn truy cập trước khi nhấp vào. Link chính thức gameswebstore.com thường có giao diện quen thuộc, hiển thị rõ tên thương hiệu và không chứa ký tự lạ. Nên truy cập từ nguồn đáng tin cậy như trang chủ Saoketv hoặc liên kết được chia sẻ trên các kênh chính thức.</li>
549<li style="font-weight: 400;" aria-level="1"><strong>Dùng trình duyệt bảo mật và tránh tải phần mềm lạ</strong>: Khi xem bóng đá trực tuyến, bạn nên sử dụng các trình duyệt phổ biến như Chrome, Firefox hoặc Edge có chế độ bảo mật cao. Tuyệt đối không cài đặt tiện ích mở rộng hoặc phần mềm được yêu cầu từ các trang không rõ ràng.</li>
550<li style="font-weight: 400;" aria-level="1"><strong>Liên hệ hỗ trợ nếu không truy cập được link</strong>:  Trong trường hợp đường dẫn chính thức bị chặn hoặc lỗi, bạn có thể liên hệ đội ngũ hỗ trợ của sao ke tv qua các kênh mạng xã hội. Họ sẽ cung cấp đường link hoạt động mới nhất và hướng dẫn chi tiết để truy cập an toàn. Việc này giúp đảm bảo bạn luôn theo dõi được các trận đấu mà không bị gián đoạn.</li>
551<li style="font-weight: 400;" aria-level="1"><strong>Không truy cập các link lạ từ mạng xã hội hoặc nhóm chia sẻ</strong>: Nhiều link giả Saoketv xuất hiện trên Facebook, Telegram hoặc các trang tin không xác thực. Các đường dẫn này thường gắn mã theo dõi hoặc chứa quảng cáo gây phiền toái. Người xem bd link nên tuyệt đối tránh truy cập các link lạ để đảm bảo an toàn thông tin cá nhân và thiết bị của mình.</li>
552</ul>
553<h2>Danh sách các kênh trực tiếp cùng hệ thống Saoketv</h2>
554<div id="attachment_1313" style="width: 810px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-1313" class="size-full wp-image-1313" src="https://cdn.enjoysmallthings.com/wp-content/uploads/2025/12/he-thong-kenh-truc-tuyen-lien-ket-voi-saoketv-7.jpg" alt="he thong kenh truc tuyen lien ket voi saoketv 7" width="800" height="400" title="Saoketv - Trang xem trực tiếp bóng đá rõ nét, ổn định 24/7 5" srcset="https://cdn.automarkhistory.com/wp-content/uploads/2025/12/he-thong-kenh-truc-tuyen-lien-ket-voi-saoketv-7.jpg 800w, https://cdn.automarkhistory.com/wp-content/uploads/2025/12/he-thong-kenh-truc-tuyen-lien-ket-voi-saoketv-7-300x150.jpg 300w, https://cdn.automarkhistory.com/wp-content/uploads/2025/12/he-thong-kenh-truc-tuyen-lien-ket-voi-saoketv-7-768x384.jpg 768w" sizes="auto, (max-width: 800px) 100vw, 800px" /><p id="caption-attachment-1313" class="wp-caption-text">Hệ thống kênh trực tuyến liên kết với Saoketv</p></div>
555<p>Sao kê tv xây dựng một hệ thống phát sóng trực tuyến rộng khắp, kết nối nhiều kênh thể thao trong và ngoài nước. Dưới đây là danh sách các kênh trực tiếp nằm trong hệ thống, mang đến cho khán giả trải nghiệm bóng đá liền mạch và phong p
555hú nhất.</p>
556<table>
557<tbody>
558<tr>
559<td>Kênh trực tiếp bóng đá</td>
560<td>Tính năng nổi bật của kênh</td>
561</tr>
562<tr>
563<td>Saoke live</td>
564<td>Sao kê live mang đến trải nghiệm xem bóng đá trực tiếp tốc độ cao với hình ảnh sắc nét ở mức 60 khung hình/giây. Trang hỗ trợ hơn 100 giải đấu lớn nhỏ mỗi năm như Ngoại Hạng Anh, La Liga, Serie A và Cúp C1. Chỉ với một cú nhấp chuột, khán giả có thể truy cập ngay trận cầu yêu thích mà không cần tải ứng dụng.</td>
565</tr>
566<tr>
567<td>Saoke 5 link</td>
568<td>Sao kê 5 link cung cấp 5 đường dẫn khác nhau giúp người xem luôn có lựa chọn khi một link gặp lỗi. Tỷ lệ ổn định đường truyền đạt tới 98%, giảm thiểu tình trạng giật, lag trong giờ cao điểm. Đây là địa chỉ đáng tin cậy cho những ai muốn xem bóng đá trơn tru, không bị gián đoạn.</td>
569</tr>
570<tr>
571<td>Saoke 6 link</td>
572<td>Saoke 6 link trực tiếp hỗ trợ xem trực tiếp trên điện thoại, máy tính và TV thông minh, phù hợp với nhiều thiết bị khác nhau. Chất lượng hình ảnh tự động điều chỉnh từ 480p đến 1080p theo tốc độ mạng của người dùng. Chỉ cần truy cập sao ke 6 link là có thể thưởng thức trận đấu mọi lúc, mọi nơi.</td>
573</tr>
574<tr>
575<td>Saoke 8 link</td>
576<td>Sao kê 8 link cập nhật đường dẫn mới chỉ trong 30 giây khi xảy ra lỗi phát sóng, giúp người xem không bỏ lỡ khoảnh khắc nào. Trang liên kết với hơn 20 kênh thể thao quốc tế, đảm bảo nguồn phát phong phú và ổn định. Ngoài ra, lịch thi đấu được hiển thị rõ ràng ngay dưới video.</td>
577</tr>
578<tr>
579<td>Saoke 10 link</td>
580<td>Saoke 10 Link nổi bật với tốc độ tải video nhanh hơn 40% so với nhiều trang bóng đá khác. Giao diện thân thiện, chỉ mất 3 giây để mở trận đấu mong muốn. Đây là lựa chọn lý tưởng cho người hâm mộ muốn xem nhanh, rõ và tiện lợi.</td>
581</tr>
582<tr>
583<td>Saoke 11 link</td>
584<td>Saoke 11 link cung cấp chất lượng hình ảnh Full HD 1080p cùng âm thanh sống động. Trang được tối ưu cho hơn 90% thiết bị di động, giúp xembd line mượt mà kể cả khi đang di chuyển. Mỗi 5 phút, hệ thống tự động cập nhật link dự phòng mới để duy trì kết nối ổn định.</td>
585</tr>
586<tr>
587<td>Saoke 12 link</td>
588<td>Saoke 12 Link có hơn 10 máy chủ hoạt động song song, giúp đảm bảo tốc độ truy cập luôn nhanh và mượt. Người xem bong da có thể chuyển giữa các trận đấu chỉ trong 2 giây mà không bị ngắt quãng. Giao diện gọn gàng, dễ thao tác, phù hợp với mọi đối tượng khán giả.</td>
589</tr>
590<tr>
591<td>Saoke 2 link</td>
592<td>Saoke 2 tv được nhiều người dùng đánh giá cao nhờ khả năng hoạt động ổn định chỉ với 3 Mbps đường truyền. Trang có tỷ lệ truy cập thành công hơn 95% trong khung giờ cao điểm. Thiết kế đơn giản, dễ dùng, giúp khán giả truy cập nhanh chóng và xem ngay không cần chờ đợi.</td>
593</tr>
594<tr>
595<td>Saoke tv</td>
596<td>Saoke tv trực tiếp bóng đá là trung tâm của hệ thống saoketv, nơi tổng hợp hơn 500 trận đấu trực tiếp mỗi tháng. Với hơn 1 triệu lượt truy cập thường xuyên, sao kê tv trực tiếp bóng đá là địa chỉ quen thuộc của fan túc cầu Việt Nam. Saoke tivi cung cấp hình ảnh Full HD, tốc độ cao, mang đến trải nghiệm bóng đá sống động và trọn vẹn nhất.</td>
597</tr>
598<tr>
599<td>Saoke link</td>
600<td>Sao kê link được xem là trung tâm kết nối các đường dẫn xem bóng đá trực tiếp nhanh, rõ và ổn định nhất trong hệ thống. Trang luôn cập nhật link trực tiếp bóng đá mới trước mỗi trận đấu, giúp khán giả dễ dàng truy cập mà không lo gián đoạn. Với tốc độ truyền tải ấn tượng, hình ảnh sắc nét và khả năng tự động thay thế khi link lỗi.</td>
601</tr>
602</tbody>
603</table>
604<h2>Saoketv cập nhật các trận trực tiếp bóng đá World Cup 2026</h2>
605<div id="attachment_1318" style="width: 810px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-1318" class="size-full wp-image-1318" src="https://cdn.enjoysmallthings.com/wp-content/uploads/2025/12/truc-tiep-world-cup-2026-toan-canh-tren-saoketv-5.jpg" alt="truc tiep world cup 2026 toan canh tren saoketv 5" width="800" height="400" title="Saoketv - Trang xem trực tiếp bóng đá rõ nét, ổn định 24/7 6" srcset="https://cdn.automarkhistory.com/wp-content/uploads/2025/12/truc-tiep-world-cup-2026-toan-canh-tren-saoketv-5.jpg 800w, https://cdn.automarkhistory.com/wp-content/uploads/2025/12/truc-tiep-world-cup-2026-toan-canh-tren-saoketv-5-300x150.jpg 300w, https://cdn.automarkhistory.com/wp-content/uploads/2025/12/truc-tiep-world-cup-2026-toan-canh-tren-saoketv-5-768x384.jpg 768w" sizes="auto, (max-width: 800px) 100v
605w, 800px" /><p id="caption-attachment-1318" class="wp-caption-text">Trực tiếp World Cup 2026 toàn cảnh giải đấu trên Saoketv</p></div>
606<p>World Cup 2026 hứa hẹn sẽ là kỳ cúp bóng đá lớn nhất lịch sử với sự góp mặt của 48 đội tuyển trên khắp thế giới. Để theo dõi trọn vẹn giải đấu, việc cập nhật các kênh và link xem trực tiếp bóng đá miễn phí như Saoketv trở nên vô cùng quan trọng.</p>
607<ul>
608<li style="font-weight: 400;" aria-level="1"><strong>Thông tin chung về World Cup 2026</strong>: Giải đấu sẽ diễn ra vào mùa hè năm 2026, kéo dài gần một tháng với hàng trăm trận cầu hấp dẫn. Đây là lần đầu tiên World Cup được tổ chức tại ba quốc gia cùng lúc.</li>
609<li style="font-weight: 400;" aria-level="1"><strong>Trực tiếp mọi trận cầu</strong>: Saoketv cung cấp lịch thi đấu và link xem trực tiếp: gameswebstore.com đầy đủ, giúp người xem dễ dàng theo dõi đội tuyển yêu thích. Từ vòng bảng đến chung kết, mọi trận đấu của World Cup 2026 đều được phát sóng với tốc độ ổn định, không giật lag.</li>
610<li style="font-weight: 400;" aria-level="1"><strong>Cập nhật tin tức, kết quả và phân tích chuyên sâu</strong>: Không chỉ dừng lại ở việc phát sóng trực tiếp, Saoketv còn mang đến tin tức nóng hổi về World Cup 2026. Người hâm mộ có thể theo dõi bảng xếp hạng, kết quả bóng đá hôm nay, tỷ lệ kèo và nhận định chuyên sâu từ các chuyên gia.</li>
611<li style="font-weight: 400;" aria-level="1"><strong>Đội ngũ bình luận viên</strong>: Các BLV của Saoketv không chỉ là người dẫn dắt trận đấu mà còn là bạn đồng hành cùng khán giả. Họ thường xuyên tương tác qua phần bình luận trực tiếp, trả lời câu hỏi và chia sẻ cảm nhận sau mỗi trận đấu.</li>
612</ul>
613<p>World Cup 2026 hứa hẹn là giải đấu bùng nổ cảm xúc và Saoketv sẽ đồng hành cùng người xem trong từng phút giây kịch tính. Hãy truy cập Saoketv để sẵn sàng cháy hết mình cùng World Cup 2026 – nơi mọi cảm xúc bóng đá được thăng hoa.</p>
614<h2>Nguyên nhân và cách khắc phục lỗi hệ thống xem bd Saoketv</h2>
615<div id="attachment_1316" style="width: 810px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-1316" class="size-full wp-image-1316" src="https://cdn.enjoysmallthings.com/wp-content/uploads/2025/12/sua-loi-khi-khong-vao-duoc-link-xem-bong-da-saoketv-5.jpg" alt="sua loi khi khong vao duoc link xem bong da saoketv 5" width="800" height="400" title="Saoketv - Trang xem trực tiếp bóng đá rõ nét, ổn định 24/7 7" srcset="https://cdn.automarkhistory.com/wp-content/uploads/2025/12/sua-loi-khi-khong-vao-duoc-link-xem-bong-da-saoketv-5.jpg 800w, https://cdn.automarkhistory.com/wp-content/uploads/2025/12/sua-loi-khi-khong-vao-duoc-link-xem-bong-da-saoketv-5-300x150.jpg 300w, https://cdn.automarkhistory.com/wp-content/uploads/2025/12/sua-loi-khi-khong-vao-duoc-link-xem-bong-da-saoketv-5-768x384.jpg 768w" sizes="auto, (max-width: 800px) 100vw, 800px" /><p id="caption-attachment-1316" class="wp-caption-text">Cách sửa lỗi khi không vào được link xem bóng đá Saoketv</p></div>
616<p>Khi xem trực tiếp bóng đá full HD hôm nay trên Saoketv, đôi lúc người xem có thể gặp phải một số lỗi hệ thống khiến trận đấu bị gián đoạn. Hiểu rõ nguyên nhân và cách khắc phục sẽ giúp bạn theo dõi trận cầu mượt mà, ổn định và trọn vẹn cảm xúc.</p>
617<h3>Nguyên nhân</h3>
618<p>Dù Saoketv luôn chú trọng mang đến chất lượng truyền phát tốt, song không tránh khỏi việc xảy ra lỗi trong quá trình xem truc tiep bd.</p>
619<ul>
620<li style="font-weight: 400;" aria-level="1"><strong>Kết nối mạng yếu hoặc không ổn định</strong>: Đây là nguyên nhân phổ biến nhất khiến video bị giật, đứng hình hoặc mất tiếng. Khi đường truyền Internet yếu, dữ liệu không thể tải đủ nhanh để hiển thị hình ảnh liên tục.</li>
621<li style="font-weight: 400;" aria-level="1"><strong>Trình duyệt chưa được cập nhật phiên bản mới</strong>: Nhiều lỗi phát sinh khi trình duyệt web đã quá cũ hoặc chứa bộ nhớ đệm (cache) đầy. Một số tiện ích mở rộng (extension) cũng có thể xung đột với trình phát của Saoketv, gây lỗi hiển thị.</li>
622<li style="font-weight: 400;" aria-level="1"><strong>
622Lỗi máy chủ hoặc quá tải người xem</strong>: Vào những trận cầu lớn, lượng người truy cập tăng đột biến khiến hệ thống phát bị quá tải. Khi đó, người xem có thể gặp lỗi “không truy cập được” hoặc “đang bảo trì”.</li>
623<li style="font-weight: 400;" aria-level="1"><strong>Phần mềm bảo mật hoặc tường lửa chặn truy cập</strong>: Một số thiết bị có phần mềm diệt virus hoặc tường lửa tự động chặn các luồng phát trực tiếp. Khi đó, trang Saoketv có thể không hiển thị hình ảnh hoặc bị giới hạn kết nối. Đây là nguyên nhân ít gặp nhưng vẫn cần lưu ý khi không thể truy cập dù mạng ổn định.</li>
624</ul>
625<h3>Khắc phục</h3>
626<p>Sau khi xác định nguyên nhân, người xem có thể chủ động áp dụng một số biện pháp đơn giản để khắc phục.</p>
627<ul>
628<li style="font-weight: 400;" aria-level="1"><strong>Cập nhật hoặc đổi sang trình duyệt mới</strong>: Người dùng nên sử dụng các trình duyệt hiện đại như Chrome, Edge hoặc Firefox bản mới nhất. Việc cập nhật giúp tương thích tốt hơn với công nghệ phát trực tiếp bóng đá hôm nay. Đồng thời, nên xóa bộ nhớ cache và cookie để tránh lỗi tải video hoặc hiển thị sai.</li>
629<li style="font-weight: 400;" aria-level="1"><strong>Nâng cấp thiết bị và đóng bớt ứng dụng chạy ngầm</strong>: Nếu thiết bị quá yếu, việc xem video chất lượng cao sẽ dễ bị giật. Bạn có thể nâng cấp phần cứng, hoặc tạm tắt các ứng dụng nền không cần thiết để tăng hiệu suất.</li>
630<li style="font-weight: 400;" aria-level="1"><strong>Tạm tắt phần mềm bảo mật khi cần thiết</strong>: Trong một số trường hợp, bạn nên tạm thời tắt tường lửa hoặc phần mềm diệt virus để kiểm tra khả năng truy cập. Sau khi xem xong, hãy bật lại để đảm bảo an toàn cho thiết bị.</li>
631<li style="font-weight: 400;" aria-level="1"><strong>Thử đổi đường dẫn hoặc link dự phòng</strong>
631: Khi máy chủ đang quá tải, Saoketv thường cung cấp nhiều đường link khác nhau cho cùng một trận đấu. Hãy thử chuyển sang link dự phòng để đảm bảo xem ổn định.</li>
632</ul>
633<h2>Quy trình để xem bóng đá trên trang Saoketv dễ dàng</h2>
634<div id="attachment_1314" style="width: 810px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-1314" class="size-full wp-image-1314" src="https://cdn.enjoysmallthings.com/wp-content/uploads/2025/12/huong-dan-xem-bong-da-truc-tiep-tren-saoketv-5.jpg" alt="huong dan xem bong da truc tiep tren saoketv 5" width="800" height="400" title="Saoketv - Trang xem trực tiếp bóng đá rõ nét, ổn định 24/7 8" srcset="https://cdn.automarkhistory.com/wp-content/uploads/2025/12/huong-dan-xem-bong-da-truc-tiep-tren-saoketv-5.jpg 800w, https://cdn.automarkhistory.com/wp-content/uploads/2025/12/huong-dan-xem-bong-da-truc-tiep-tren-saoketv-5-300x150.jpg 300w, https://cdn.automarkhistory.com/wp-content/uploads/2025/12/huong-dan-xem-bong-da-truc-tiep-tren-saoketv-5-768x384.jpg 768w" sizes="auto, (max-width: 800px) 100vw, 800px" /><p id="caption-attachment-1314" class="wp-caption-text">Hướng dẫn các bước xem bóng đá trực tiếp trên Saoketv</p></div>
635<p>Saoketv mang đến cho người dùng trải nghiệm xem bd truc tiep keo nha cai nhanh, mượt và dễ thao tác dù ở bất kỳ đâu. Để giúp bạn theo dõi các trận cầu yêu thích một cách trọn vẹn, dưới đây là quy trình chi tiết và dễ thực hiện nhất.</p>
636<h3>Mở trang web Saoketv bằng trình duyệt Internet</h3>
637<p>Để bắt đầu, hãy mở trình duyệt bạn thường dùng như Chrome, Safari hoặc Cốc Cốc và gõ “Saoketv” vào thanh tìm kiếm. Chọn đúng địa chỉ trang web chính thức để đảm bảo an toàn và tránh các đường link giả mạo. Khi truy cập thành công, giao diện chính sẽ hiển thị danh sách các trận đấu sắp và đang diễn ra.</p>
638<h3>Tìm và chọn trận đấu yêu thích</h3>
639<p>Ngay tại trang chủ, Saoketv hiển thị rõ ràng lịch thi đấu của các giải bóng lớn như Ngoại Hạng Anh, C1, La Liga hay Serie A. Bạn có thể cuộn xuống để tìm đội bóng mình yêu thích hoặc sử dụng thanh tìm kiếm để chọn nhanh. Khi nhấp vào tên trận đấu, trình phát video sẽ tự động mở ra trong vài giây. Giao diện đơn giản, rõ ràng giúp ai cũng có thể thao tác dễ dàng, kể cả người mới sử dụng.</p>
640<h3>Cấu hình chất lượng video phù hợp với đường truyền</h3>
641<p>Khi trận đấu bắt đầu phát, người xem bd trực tuyến có thể điều chỉnh độ phân giải hình ảnh từ thấp đến cao tùy theo tốc độ mạng. Khi Internet đạt tốc độ cao, bạn có thể theo dõi trận đấu sắc nét và mượt mà ở chế độ Full HD. Nếu mạng yếu, hãy chọn chất lượng thấp hơn để hình ảnh tải nhanh và không bị gián đoạn.</p>
642<h3>Tận hưởng trận đấu và tham gia tương tác trực tiếp</h3>
643<p>Khi đã ổn định chất lượng xem, bạn chỉ cần ngồi lại và tận hưởng bầu không khí sôi động của trận cầu. Saoketv còn tích hợp khung bình luận trực tiếp để người xem bd trực tiếp chia sẻ cảm xúc hoặc dự đoán tỉ số cùng cộng đồng yêu bóng đá. Những bình luận, phân tích và phản ứng của khán giả giúp trận đấu thêm phần thú vị.</p>
644<h2>Các đáng giá của người dùng về trang trực tiếp bóng đá saoketv</h2>
645<div id="attachment_1319" style="width: 810px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-1319" class="size-full wp-image-1319" src="https://cdn.enjoysmallthings.com/wp-content/uploads/2025/12/y-kien-nguoi-dung-ve-xem-bong-da-tren-saoketv-5.jpg" alt="y kien nguoi dung ve xem bong da tren saoketv 5" width="800" height="400" title="Saoketv - Trang xem trực tiếp bóng đá rõ nét, ổn định 24/7 9" srcset="https://cdn.automarkhistory.com/wp-content/uploads/2025/12/y-kien-nguoi-dung-ve-xem-bong-da-tren-saoketv-5.jpg 800w, https://cdn.automarkhistory.com/wp-content/uploads/2025/12/y-kien-nguoi-dung-ve-xem-bong-da-tren-saoketv-5-300x150.jpg 300w, https://cdn.automarkhistory.com/wp-content/uploads/2025/12/y-kien-nguoi-dung-ve-xem-bong-da-tren-saoketv-5-768x384.jpg 768w" sizes="auto, (max-width: 800px) 100v
645w, 800px" /><p id="caption-attachment-1319" class="wp-caption-text">Ý kiến người dùng về trải nghiệm xem bóng đá trên SaokeTV</p></div>
646<p>Trang trực tiếp bóng đá SaokeTV đã nhanh chóng trở thành địa chỉ quen thuộc với những người yêu thích bóng đá. Dưới đây là tổng hợp các phản hồi từ cộng đồng người xem về trải nghiệm.</p>
647<ul>
648<li style="font-weight: 400;" aria-level="1"><strong>Trần Minh</strong>: “Tôi đã thử nhiều trang xem bd truc tuyen, nhưng Saoketv vẫn là lựa chọn hàng đầu. Mọi trận đấu tôi quan tâm đều có ở đây, không cần phải tìm link từ nhiều nguồn.”</li>
649<li style="font-weight: 400;" aria-level="1"><strong>Nguyễn Hoàng</strong>: “Tôi thích Saoketv vì tốc độ load video nhanh, không phải chờ lâu như nhiều trang khác. Âm thanh sống động, đúng chuẩn chất lượng HD. Tôi cũng đánh giá cao việc trang web ít quảng cáo gây phiền, giúp trải nghiệm xem bóng đá trọn vẹn hơn.”</li>
650<li style="font-weight: 400;" aria-level="1"><strong>Ngọc Hân</strong>: “Một điểm cộng nữa là Saoketv cho phép bình luận trực tiếp ngay trên video. Tôi vừa xem trận đấu vừa trao đổi cảm xúc với các fan khác, tạo cảm giác như đang xem cùng bạn bè. Thật sự rất thú vị và tiện lợi.”</li>
651<li style="font-weight: 400;" aria-level="1"><strong>Minh Tú</strong>: “Tôi thường xem trực tiếp bóng đá bằng điện thoại và đường truyền 4G, nhưng Saoketv vẫn chạy rất ổn định. Không bị đứng hình hay giật lag như nhiều trang khác.”</li>
652</ul>
653<h2>FAQ &#8211; Danh mục câu hỏi thường gặp khi xem trực tuyến bóng đá tại Saoketv</h2>
654<div id="attachment_1311" style="width: 810px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-1311" class="size-full wp-image-1311" src="https://cdn.enjoysmallthings.com/wp-content/uploads/2025/12/cau-hoi-pho-bien-cua-nguoi-xem-bong-da-tren-saoketv-7.jpg" alt="cau hoi pho bien cua nguoi xem bong da tren saoketv 7" width="800" height="400" title="Saoketv - Trang xem trực tiếp bóng đá rõ nét, ổn định 24/7 10" srcset="https://cdn.automarkhistory.com/wp-content/uploads/2025/12/cau-hoi-pho-bien-cua-nguoi-xem-bong-da-tren-saoketv-7.jpg 800w, https://cdn.automarkhistory.com/wp-content/uploads/2025/12/cau-hoi-pho-bien-cua-nguoi-xem-bong-da-tren-saoketv-7-300x150.jpg 300w, https://cdn.automarkhistory.com/wp-content/uploads/2025/12/cau-hoi-pho-bien-cua-nguoi-xem-bong-da-tren-saoketv-7-768x384.jpg 768w" sizes="auto, (max-width: 800px) 100vw, 800px" /><p id="caption-attachment-1311" class="wp-caption-text">Câu hỏi phổ biến của người xem bóng đá trên Saoketv</p></div>
655<p>Khi xem bđ trực tiếp hôm nay người hâm mộ đôi khi gặp phải một số tình huống khiến trải nghiệm bị gián đoạn hoặc cần được giải đáp kịp thời. Dưới đây là những thắc mắc thường gặp và lời giải thích cụ thể để bạn sử dụng Saoketv một cách thuận tiện và an toàn nhất.</p>
656<h3>Làm sao biết đâu là link xembd chính thức của Saoketv?</h3>
657<p>Hiện nay, có nhiều trang giả mạo lợi dụng tên Saoketv để lừa người dùng truy cập vào đường dẫn không an toàn. Để tránh điều này, bạn nên tìm link chính thức thông qua trang fanpage, kênh cộng đồng hoặc kết quả tìm kiếm có dấu “https://” trên Google. Ngoài ra, Saoketv thường xuyên cập nhật đường dẫn mới trên các trang mạng xã hội chính thức để người xem dễ dàng nhận biết và truy cập.</p>
658<h3>Vì sao đôi khi không xem được trận đấu trên Saoketv?</h3>
659<p>Tình trạng không xem được có thể xảy ra do sự cố đường truyền, trình duyệt bị lỗi hoặc server quá tải trong giờ cao điểm. Bạn nên tải lại trang, đổi thiết bị khác hoặc kiểm tra kết nối mạng. Trong trường hợp sự cố đến từ phía hệ thống, Saoketv sẽ khắc phục và cập nhật link mới trong thời gian sớm nhất để người dùng tiếp tục xem mà không bị gián đoạn.</p>
660<h3>Có cần tài khoản để xem bóng đá trực tuyến trên Saoketv không?</h3>
661<p>Không. Saoketv cho phép người dùng xem bóng đá trực tiếp hoàn toàn miễn phí mà không yêu cầu đăng ký hay đăng nhập. Bạn chỉ cần truy cập đúng đường dẫn là có thể xem ngay. Nếu gặp trang yêu 
661cầu nhập thông tin cá nhân, hãy dừng lại vì đó có thể là website giả mạo, không thuộc hệ thống Saoketv.</p>
662<h3>Saoketv có hỗ trợ xem lại trận đấu cũ không?</h3>
663<p>Saoketv thường cập nhật phần “Highlight”, “Video ngắn” và kết quả bóng đá sau khi trận đấu kết thúc. Người xem có thể truy cập chuyên mục này để theo dõi lại các pha bóng hay, bàn thắng đẹp hoặc tình huống nổi bật</p>
664<h3>Làm sao để cập nhật lịch thi đấu và giờ phát sóng mới nhất?</h3>
665<p>Tại trang chủ Saoketv, mục “Lịch thi đấu” luôn được cập nhật mỗi ngày với đầy đủ thông tin giờ phát sóng, đội hình và sân vận động. Bạn cũng có thể theo dõi fanpage chính thức để nhận thông báo về các trận cầu sắp diễn ra. Tất cả giúp bạn không bỏ lỡ bất kỳ trận bóng nào, dù là giải quốc nội hay quốc tế.</p>
666<h3>Có cần trả phí khi xem bóng đá trên Saoketv không?</h3>
667<p>Saoketv cung cấp dịch vụ xem bóng đá miễn phí cho toàn bộ người hâm mộ. Mọi trận đấu đều được phát truc tiep bong da mà không yêu cầu thanh toán hay đăng ký gói thành viên. Tuy nhiên, một số nội dung đặc biệt hoặc sự kiện lớn có thể được giới hạn trong thời gian nhất định, và thông tin này sẽ luôn được công bố công khai trước khi phát sóng.</p>
668<h2>Tổng kết</h2>
669<p>Saoketv đã trở thành lựa chọn quen thuộc của cộng đồng người hâm mộ bóng đá Việt Nam. Nơi đây không chỉ mang đến những trận cầu đỉnh cao, mà còn kết nối cảm xúc và niềm đam mê của hàng triệu khán giả. Mỗi lần xem bd truc tuyen hom nay là một hành trình sống trọn cùng bóng đá, từ những pha bóng nghẹt thở đến giây phút ăn mừng chiến thắng.</p>
670          </div>
671        </div>
672      </div>
673    </div>
674  </div>
675</section>
676    </main>
677    
677<script>
678// Sample data (trận đấu)
679const matches = {};
680</script>
680
681<!-- Footer -->
682<!-- <footer class="footer">
683      <div class="container">
684        <div class="footer__content">
685          <p style="font-size: 14px">
686            Bản quyền bởi
687            <a href="#"><span class="text-primary">CakhiaTV</span></a> - All
688            rights reserved
689          </p>
690        </div>
691      </div>
692    </footer> -->
693
694<footer style="  padding: 30px 15px;">
695     <div class="container">
696    <div class="footer-column">
697          <div class="footer-logo">
698             <img src="https://cdn.automarkhistory.com/wp-content/themes/cakhiatv/assets/images/saoketvlogo.png" alt="Xoilac TV" style="vertical-align: middle; height: 90px;">
699        </div>
700          <p class="footer-descript">
701               <p><a href="/"><strong>Saoketv</strong></a> là nền tảng trực tiếp bóng đá được nhiều người tin chọn theo dõi các trận đấu lớn nhỏ, từ giải quốc nội đến quốc tế, với hình ảnh sắc nét và âm thanh rõ ràng. Sao ke tv không chỉ phát sóng bóng đá trực tiếp uy tín và miễn phí mà trang còn cập nhật lịch thi đấu, tỷ số và thông tin bóng đá liên tục, giúp người xem bóng đá nắm bắt diễn biến nhanh chóng.</p>
702        </p>
703       
704      
705
706       
707    </div>
708
709    <div class="footer-column list">
710         <div class="footer-title">
711          DANH MỤC
712        </div>
713            <ul>
714<li><strong><a href="/dieu-khoan-su-dung">Điều khoản sử dụng</a></strong></li>
715<li><strong><a href="/chinh-sach-bao-mat">Chính sách bảo mật</a></strong></li>
716<li><strong><a href="/mien-tru-trach-nhiem">Miễn trừ trách nhiệm</a></strong></li>
717<li><a href="/lien-he"><strong>Liên hệ</strong></a></li>
718</ul>
719    </div>
720    
721  
722
723       <div class="footer-column">
724        <div class="footer-title">
725            THÔNG TIN CHUNG
726        </div>
727            <ul>
728<li class="footer-text"><strong>Tên doanh nghiệp</strong>: <strong>SAOKETV</strong></li>
729<li class="footer-text"><strong>Số điện thoại</strong>: 0938 368 997</li>
730<li class="footer-text"><strong>Email</strong>: <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="0271636d69677674767660663a3a3b42656f636b6e2c616d6f">[email&#160;protected]</a></li>
731<li class="footer-text"><strong>Địa chỉ</strong>: <a href="https://maps.app.goo.gl/fxEF76cXCfRphGTL9">219/3 Trần Hưng Đạo, Phường Cô Giang, Quận 1, Thành phố Hồ Chí Minh, Vietnam</a></li>
732<li class="footer-text"><strong>Website</strong>: <a href="/">https://gameswebstore.com/</a></li>
733</ul>
734     <div style="margin-top: 15px;">
735        <a href="#"><img src="https://cdn.automarkhistory.com/wp-content/wp-content/uploads/2025/04/icon-facebook.webp" alt="Facebook" style="width: 24px; margin: 0 5px;"></a>
736        <a href="#" rel="nofollow" target="_blank"><img src="/wp-content/uploads/2025/04/twitter_x-logo-freelogovectors.net_.png" alt="Twitter" style="width: 24px; margin: 0 5px;"></a>
737        <a href="#" rel="nofollow" target="_blank"><img src="https://cdn.automarkhistory.com/wp-content/wp-content/uploads/2025/04/pngimg.com-twitch_PNG28.png" alt="Twitch" style="width: 24px; margin: 0 5px;"></a>
738        <a href="#" rel="nofollow" target="_blank"><img src="https://cdn.automarkhistory.com/wp-content/wp-content/uploads/2025/04/Youtube_logo.png" alt="Youtube" style="width: 24px; margin: 0 5px;"></a>
739        <a href="#" rel="nofollow" target="_blank"><img src="https://cdn.automarkhistory.com/wp-content/wp-content/uploads/2025/04/reddit-logo-1.png" alt="Reddit" style="width: 24px; margin: 0 5px;"></a>
740        <a href="#" rel="nofollow" target="_blank"><img src="https://cdn.automarkhistory.com/wp-content/wp-content/uploads/2025/04/pngimg.com-pinterest_PNG63.png" alt="Pinterest" style="width: 24px; margin: 0 5px;"></a>
741        <a href="#" rel="nofollow" target="_blank"><img src="https://cdn.automarkhistory.com/wp-content/wp-content/uploads/2025/04/free-tumblr-logo-icon-2434-thumb.png" alt="Tumblr" style="width: 24px; margin: 0 5px;"></a>
742    </div>
743    </div>
744
745
746
747 </div>
748
749    
750
751   
752</footer>
753
754
755<button onclick="scrollToTop()" id="scrollTopBtn" title="Go to top">
756    <svg viewBox="0 0 24 24">
757        <path
758            d="M13,20H11V8L5.5,13.5L4.08,12.08L12,4.16L19.92,12.08L18.5,13.5L13,8V20Z"></path>
759    </svg>
760</button>
vendor: 110 bytes, lines 760-762
760
761
762<script data-cfasync="false" src="/cdn-cgi/scripts/5c5dd728/cloudflare-static/email-decode.min.js"></script>
762<script src="https://cdn.automarkhistory.com/wp-content/themes/cakhiatv/assets/js/main.js"></script>
762
763
764<script type="module" src="https://static.cloudflareinsights.com/beacon.min.js/v31edd6df95cf4e85bb4c19e7a9bdbcba1788362987495" integrity="sha512-iIg7k2xntmwu6/uSb5tpc/hySgZc4eoL31yB29W6tJFo2akwjPWcEqnCEdJvGexCL0KEQwVYv5BlowfhVz26hg==" data-cf-beacon='{"version":"2024.11.0","token":"005e8f941b7f4ea08939c08c22aed489","r":1,"spa":2}' crossorigin="anonymous"></script>
764
765</body>
766    
766<script>
767        if ('serviceWorker' in navigator) {
768            window.addEventListener('load', function () {
769                navigator.serviceWorker.register('/sw.js')
770                    .then(function (reg) { /*console.log('[SW] ✅ Registered, scope:', reg.scope);*/ })
771                    .catch(function (err) { /*console.warn('[SW] Registration failed:', err);*/ });
772            });
773        }
774    </script>
774
775    
775<script type="speculationrules">
776{"prefetch":[{"source":"document","where":{"and":[{"href_matches":"\/*"},{"not":{"href_matches":["\/wp-*.php","\/wp-admin\/*","\/wp-content\/uploads\/*","\/wp-content\/*","\/wp-content\/plugins\/*","\/wp-content\/themes\/cakhiatv\/*","\/*\\?(.+)"]}},{"not":{"selector_matches":"a[rel~=\"nofollow\"]"}},{"not":{"selector_matches":".no-prefetch, .no-prefetch a"}}]},"eagerness":"conservative"}]}
777</script>
777
778        
778<script src="https://www.automarkhistory.com/js/websocket-client.js"></script>
778
779        <style>
780            @keyframes spin {
781                0% {
782                    transform: rotate(0deg);
783                }
784
785                100% {
786                    transform: rotate(360deg);
787                }
788            }
789
790            .loading-spinner {
791                animation: spin 1s linear infinite;
792            }
793
794            #match-list {
795                position: relative;
796            }
797
798            #match-list>div[style*="display: flex"] {
799                width: 100% !important;
800                max-width: 100% !important;
801            }
802        </style>
803        
803<script>
804            // ─── LocalStorage Cache (giống colatv40.live) ────────────────
805            const LS_MATCHES_KEY = 'colatv_matches_v1';
806            const LS_MATCHES_TTL = 10 * 60 * 1000; // 10 phút
807
808            function loadMatchesFromCache() {
809                try {
810                    const raw = localStorage.getItem(LS_MATCHES_KEY);
811                    if (!raw) return null;
812                    const { data, ts } = JSON.parse(raw);
813                    if (!data || !Array.isArray(data) || data.length === 0) return null;
814                    if (Date.now() - ts > LS_MATCHES_TTL) return null;
815                    return data;
816                } catch { return null; }
817            }
818
819            function saveMatchesToCache(matches) {
820                try {
821                    if (!matches || matches.length === 0) return;
822                    localStorage.setItem(LS_MATCHES_KEY, JSON.stringify({ data: matches, ts: Date.now() }));
823                } catch { /* localStorage full, bỏ qua */ }
824            }
825            // ─────────────────────────────────────────────────────────────
826
827            // Tối ưu: Cache DOM selectors để tránh query lại
828            const filterCountCache = {
829                countAllType: null,
830                countAll: null,
831                countElements: {},
832                noBlvElement: null,
833                liveElement: null,
834                hotElement: null,
835                todayElement: null,
836                tomorrowElement: null,
837                initialized: false
838            };
839
840            function initFilterCountCache() {
841                if (filterCountCache.initialized) return;
842
843                filterCountCache.countAllType = document.getElementById('count-all-type');
844                filterCountCache.countAll = document.getElementById('count-all');
845                filterCountCache.noBlvElement = document.getElementById('noblv-live');
846                filterCountCache.liveElement = document.getElementById('count-live');
847                filterCountCache.hotElement = document.getElementById('count-hot');
848                filterCountCache.todayElement = document.getElementById('count-today');
849                filterCountCache.tomorrowElement = document.getElementById('count-tomorrow');
850
851                ['football', 'basketball', 'tennis', 'volleyball'].forEach(sport => {
852                    filterCountCache.countElements[sport] = document.getElementById(`count-${sport}`);
853                });
854
855                filterCountCache.initialized = true;
856            }
857
858            // Hàm đếm số lượng trận đấu theo bộ lọc - Tối ưu với cached selectors
859            function updateFilterCounts(visibleMatchCards, allMatchCards) {
860                initFilterCountCache();
861
862                if (filterCountCache.countAllType) {
863                    filterCountCache.countAllType.textContent = allMatchCards.length;
864                }
865
866                if (filterCountCache.countAll) {
867                    filterCountCache.countAll.textContent = visibleMatchCards.length;
868                }
869
870                ['football', 'basketball', 'tennis', 'volleyball'].forEach(sport => {
871                    const countElement = filterCountCache.countElements[sport];
872                    if (countElement) {
873                        const count = Array.from(allMatchCards).filter(card => card.dataset.sport === sport).length;
874                        countElement.textContent = count;
875                    }
876                });
877
878                if (filterCountCache.noBlvElement) {
879                    const noBlvCount = Array.from(visibleMatchCards).filter(card => card.dataset.blv === 'false').length;
880                    filterCountCache.noBlvElement.textContent = noBlvCount;
881                }
882
883                if (filterCountCache.liveElement) {
884                    const noBlvCount = Array.from(visibleMatchCards).filter(card => card.dataset.blv === 'false').length;
885                    const liveCount = Array.from(visibleMatchCards).filter(card => card.dataset.live === 'true').length - noBlvCount;
886                    filterCountCache.liveElement.textContent = liveCount;
887                }
888
889                if (filterCountCache.hotElement) {
890                    const noBlvCount = Array.from(visibleMatchCards).filter(card => card.dataset.blv === 'false').length;
891                    const hotCount = Array.from(visibleMatchCards).filter(card => card.dataset.hot === 'true').length - noBlvCount;
892                    filterCountCache.hotElement.textContent = hotCount;
893                }
894
895                const today = new Date().toISOString().split('T')[0];
896                const tomorrow = new Date(Date.now() + 86400000).toISOString().split('T')[0];
897
898                if (filterCountCache.todayElement) {
899                    const todayCount = Array.from(visibleMatchCards).filter(card => card.dataset.date === today).length;
900                    filterCountCache.todayElement.textContent = todayCount;
901                }
902
903                if (filterCountCache.tomorrowElement) {
904                    const tomorrowCount = Array.from(visibleMatchCards).filter(card => card.dataset.date === tomorrow).length;
905                    filterCountCache.tomorrowElement.textContent = tomorrowCount;
906                }
907            }
908
909            // Hàm chuyển đổi ID môn thể thao thành tên
910            function sportName(sportId) {
911                const sports = {
912                    1: 'football',
913                    2: 'basketball',
914                };
915                return sports[sportId] || 'unknown';
916            }
917
918            // Hàm xử lý timestamp
919            function fixtime(timestamp) {
920                return isNaN(timestamp) ? new Date(timestamp).getTime() : timestamp;
921            }
922
923            // Hàm định dạng ngày giờ
924            function formatDate(timestamp, format) {
925                const date = new Date(timestamp * 1000);
926                const day = String(date.getDate()).padStart(2, '0');
927                const month = String(date.getMonth() + 1).padStart(2, '0');
928                const year = date.getFullYear();
929                const hours = String(date.getHours()).padStart(2, '0');
930                const minutes = String(date.getMinutes()).padStart(2, '0');
931                if (format === 'd/m') return `${day}/${month}`;
932                if (format === 'Y-m-d') return `${year}-${month}-${day}`;
933                if (format === 'H:i') return `${hours}:${minutes}`;
934                return date;
935            }
936
937            // Hàm lấy domain API random để tránh Cloudflare rate limit
938            function getApiDomain() {
939                const domains = ['api.gvapi.cc'];
940
941                // Random chọn một domain
942                const index = Math.floor(Math.random() * domains.length);
943                const selected = domains[index];
944
945                return 'https://' + selected;
946            }
947
948            // Hàm lấy domain API random cho video-home (pinned-home)
949            function getVideoHomeApiDomain() {
950                const domains = ['video-home.gvapi.cc'];
951
952                // Random chọn một domain
953                const index = Math.floor(Math.random() * domains.length);
954                const selected = domains[index];
955
956                return 'https://' + selected;
957            }
958
959            // Hàm hiển thị loading
960            function showLoading() {
961                const matchList = getMatchList();
962                if (!matchList) return;
963
964                // Hiển thị trực tiếp trong match-list, thay thế toàn bộ nội dung
965                matchList.innerHTML = `
966                <div style="text-align: center; padding: 60px 20px; width: 100%; min-height: 400px; display: flex; flex-direction: column; justify-content: center; align-items: center; box-sizing: border-box;">
967                    <div class="loading-spinner" style="display: block; width: 50px; height: 50px; border: 4px solid #f3f3f3;
967 border-top: 4px solid #3498db; border-radius: 50%; animation: spin 1s linear infinite; margin: 0 auto;"></div>
968                    <p style="margin-top: 20px; color: #666; font-size: 16px; text-align: center; width: 100%;">Đang tải dữ liệu...</p>
969                </div>
970            `;
971            }
972
973            // Hàm hiển thị lỗi với các button đề xuất
974            function showErrorWithSuggestions() {
975                const matchList = getMatchList();
976                if (!matchList) return;
977
978                const suggestionLinks = [
979                    { name: 'iotditr.com', url: 'https://iotditr.com' },
980                    { name: 'cntsiend.com', url: 'https://cntsiend.com' },
981                    { name: 'euwygrb.com', url: 'https://euwygrb.com' },
982                    { name: 'ppoemlg.com', url: 'https://ppoemlg.com' },
983                    { name: 'eyhtldu.com', url: 'https://eyhtldu.com' }
984                ];
985
986                const buttonsHtml = suggestionLinks.map(link =>
987                    `<a href="${link.url}" target="_blank" rel="nofollow" style="display: inline-block; margin: 8px; padding: 12px 24px; background-color: #3498db; color: white; text-decoration: none; border-radius: 5px; font-weight: bold; transition: background-color 0.3s; cursor: pointer;">${link.name}</a>`
988                ).join('');
989
990                // Hiển thị trực tiếp trong match-list, thay thế toàn bộ nội dung
991                matchList.innerHTML = `
992                <div style="text-align: center; padding: 60px 20px; width: 100%; min-height: 400px; display: flex; flex-direction: column; justify-content: center; align-items: center;">
993                    <div style="margin-bottom: 20px;">
994                        <svg width="64" height="64" viewBox="0 0 24 24" fill="none" stroke="#e74c3c" stroke-width="2" style="margin: 0 auto; display: block;">
995                            <circle cx="12" cy="12" r="10"></circle>
996                            <line x1="12" y1="8" x2="12" y2="12"></line>
997                            <line x1="12" y1="16" x2="12.01" y2="16"></line>
998                        </svg>
999                    </div>
1000                    <h3 style="color: #e74c3c; margin-bottom: 15px; font-size: 24px; font-weight: bold;">Hệ thống gặp sự cố</h3>
1001                    <p style="color: #666; margin-bottom: 30px; font-size: 16px; max-width: 500px;">Bạn có thể chọn kênh khác:</p>
1002                    <div style="display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; width: 100%; max-width: 800px;">
1003                        ${buttonsHtml}
1004                    </div>
1005                </div>
1006            `;
1007            }
1008
1009            // Hàm fetch với timeout
1010            function fetchWithTimeout(url, timeout = 10000) {
1011                return Promise.race([
1012                    fetch(url),
1013                    new Promise((_, reject) =>
1014                        setTimeout(() => reject(new Error('Request timeout')), timeout)
1015                    )
1016                ]);
1017            }
1018
1019            // Hàm lấy dữ liệu trận đấu từ API và render
1020            async function refreshMatches() {
1021                const matchList = getMatchList();
1022                if (!matchList) {
1023                    console.error('Không tìm thấy phần tử match-list');
1024                    return;
1025                }
1026
1027                // Chỉ hiển thị loading nếu chưa có data từ cache
1028                if (!matchList.querySelector('.match-card')) {
1029                    showLoading();
1030                }
1031
1032                try {
1033                    const apiBase = getApiDomain();
1034                    const response = await fetchWithTimeout(apiBase + '/api/matches?t=' + new Date().getTime(), 10000);
1035
1036                    if (!response.ok) {
1037                        throw new Error('Lỗi khi lấy dữ liệu API: ' + response.status);
1038                    }
1039
1040                    const datas = await response.json();
1041
1042                    if (!datas.data || typeof datas.data !== 'object') {
1043                        throw new Error('Cấu trúc dữ liệu API không hợp lệ');
1044                    }
1045
1046                    const newMatches = [];
1047                    const matchesByGroup = {}; // Nhóm matches theo competitionName
1048
1049                    for (const [key, data] of Object.entries(datas.data)) {
1050                        // Bảo vệ nếu anchorAppointmentVoList không phải array
1051                        const anchorList = Array.isArray(data.anchorAppointmentVoList) ? data.anchorAppointmentVoList : [];
1052                        //if (!anchorList.length) continue;
1053
1054                        // Bỏ các trận "Live streaming"
1055                        if (anchorList[0]?.nickName === 'Live streaming') continue;
1056
1057                        // Bảo vệ tỉ số
1058                        const homeScoreArr = Array.isArray(data.homeScore) ? data.homeScore : [];
1059                        const awayScoreArr = Array.isArray(data.awayScore) ? data.awayScore : [];
1060                        const homeScore = homeScoreArr.length ? homeScoreArr[0] : 0;
1061                        const awayScore = awayScoreArr.length ? awayScoreArr[0] : 0;
1062
1063                        // Nếu match có house_id khác null, thêm ?houseId=... vào slug
1064                        let slug = key;
1065                        if (data.house_id && data.house_id !== null) {
1066                            slug = `${key}?houseId=${data.house_id}`;
1067                        }
1068
1069                        const competitionName = data.competitionName || 'NBA';
1070                        const matchData = {
1071                            id: 2,
1072                            slug: slug,
1073                            sport: sportName(data.sportId),
1074                            live: data.matchStatus === 2,
1075                            hot: true,
1076                            blv: anchorList[0]?.nickName !== 'Live streaming',
1077                            date: formatDate(fixtime(data.matchTime), 'd/m'),
1078                            datesearch: formatDate(fixtime(data.matchTime), 'Y-m-d'),
1079                            hour: formatDate(fixtime(data.matchTime), 'H:i'),
1080                            competitionName: competitionName,
1081                            teams: [
1082                                data.homeTeamName || 'Team C',
1083                                data.awayTeamName || 'Team D'
1084                            ],
1085                            score: `${homeScore}:${awayScore}`,
1086                            videoUrl: data.videoUrl || 'https://live2.example.com',
1087                            animationUrl: data.animationUrl || 'https://animation.example.com',
1088                            data: data
1089                        };
1090
1091                        newMatches.push(matchData);
1092
1093                        // Nhóm matches theo competitionName
1094                        if (!matchesByGroup[competitionName]) {
1095                            matchesByGroup[competitionName] = [];
1096                        }
1097                        matchesByGroup[competitionName].push(matchData);
1098                    }
1099
1100                    // Gọi hàm render với danh sách trận đấu mới
1101                    renderAllMatches(newMatches);
1102                    filterMatches('parent', newMatches);
1103                    saveMatchesToCache(newMatches); // 
1104                } catch (error) {
1105                    console.error('Lỗi khi làm mới trận đấu:', error);
1106                    // Đã loại bỏ showErrorWithSuggestions() để không ghi đè giao diện SSR nếu API thất bại ở lần gọi đầu tiên.
1107                    // Hệ thống sẽ âm thầm giữ nguyên giao diện SSR và đợi Socket cập nhật.
1108                }
1109            }
1110
1111            function createMatchCard(match) {
1112                // Bảo vệ dữ liệu, tránh crash nếu cache cũ thiếu data
1113                if (!match || !match.data) return '';
1114
1115                // Bảo vệ anchorAppointmentVoList
1116                const anchorList = Array.isArray(match.data.anchorAppointmentVoList)
1117                    ? match.data.anchorAppointmentVoList
1118                    : [];
1119
1120                // Xử lý slug an toàn
1121                const slugStr = match.slug || '';
1122                const baseSlug = slugStr.includes('?') ? slugStr.split('?')[0] : slugStr;
1123
1124                const nicknames = anchorList.map(item => {
1125                    const itemHouseId = item.houseId || '';
1126                    if (itemHouseId !== '') {
1127                        const separator = baseSlug.includes('?') ? '&' : '?';
1128                        return `<a href="https://www.automarkhistory.com/truc-tiep/${baseSlug}${separator}houseId=${itemHouseId}" rel="nofollow">${item.nickName}</a>`;
1129                    } else {
1130                        return `<a href="https://www.automarkhistory.com/truc-tiep/${slugStr}" rel="nofollow">${item.nickName}</a>`;
1131                    }
1132                });
1133
1134                const nicknameString = nicknames.join(' | ');
1135
1136                // Bảo vệ tỉ số (dùng lại match.score nếu muốn)
1137                const homeScoreArr = Array.isArray(match.data.homeScore) ? match.data.homeScore : [];
1138                const awayScoreArr = Array.isArray(match.data.awayScore) ? match.data.awayScore : [];
1139                const homeScore = homeScoreArr.length ? homeScoreArr[0] : 0;
1140                const awayScore = awayScoreArr.length ? awayScoreArr[0] : 0;
1141
1142                return `
1143                <div class="match-card" data-id="${match.id}" data-sport="${match.sport}" data-live="${match.live}" data-blv="${match.blv}" data-hot="${match.hot}" data-date="${match.datesearch}">
1144                    <div class="match-card__body">
1145                        <a href="https://www.automarkhistory.com/truc-tiep/${match.slug}" class="link-match" rel="nofollow"></a>
1146                        <div class="match-card__header">
1147                            <div class="match-card__league">
1148                                <span>${match.data.competitionName}</span>
1149                            </div>
1150                            <div class="match-card__status">
1151                                ${match.data.matchStatus == 1
1152                ? '<div class="match-card__status text-warning text-uppercase">CHƯA BẮT ĐẦU</div>'
1153                : match.data.matchStatus == 2
1154                    ? '<div class="match-card__status streaming">ĐANG TRỰC TIẾP</div>'
1155                    : match.data.matchStatus == 3
1156                        ? '<span class="btn btn--warning text-uppercase">Tạm ngừng phát sóng</span>'
1157                        : match.data.matchStatus == 4
1158                            ? '<span class="btn btn--danger text-uppercase">Cấm phát sóng vĩnh viễn</span>'
1159                            : '<span class="btn btn--secondary text-uppercase">Không xác định</span>'
1160            }
1161                            </div>
1162                            <div class="match-card__time"><span class="match-time">${match.hour} - ${match.date}</span></div>
1163                        </div>
1164                        <div class="match-card__teams">
1165                            <div class="team home">
1166                                <img src="${match.data.homeTeamLogo}" alt="${match.data.homeTeamName}" class="team__logo">
1167                                <span class="team__name">${match.data.homeTeamName}</span>
1168                            </div>
1169                            <div class="match-card__score">${homeScore} - ${awayScore}</div>
1170                            <div class="team">
1171                                <img src="${match.data.awayTeamLogo}" alt="${match.data.awayTeamName}" class="team__logo">
1172                                <span class="team__name">${match.data.awayTeamName}</span>
1173                            </div>
1174                        </div>
1175                        <div class="match-card__info">
1176                            <div class="match-card__stats">
1177                                <div class="match-card__stats-content">
1178                                    ${nicknameString}
1179                                </div>
1180                            </div>
1181                            <div class="match-card__odds">
1182                                <a href="https://www.automarkhistory.com/truc-tiep/${match.slug}" class="btn btn--primary" rel="nofollow">
1183                                    <span>XEM NGAY</span>
1184                                </a>
1185                            </div>
1186                        </div>
1187                    </div>
1188                </div>
1189            `;
1190            }
1191
1192            // Khởi tạo bộ lọc
1193            let currentFilters = {
1194                sport: 'all',
1195                live: false,
1196                blv: false,
1197                hot: false,
1198                commentator: false,
1199                date: 'all',
1200                league: 'all'
1201            };
1202
1203            // Tối ưu: Preload video metadata để tăng tốc độ load khi click vào match
1204            const videoPreloadCache = new Map(); // Cache preloaded videos
1205            function preloadVideoMetadata(videoUrl) {
1206                if (!videoUrl || videoPreloadCache.has(videoUrl)) {
1207                    return; // Đã preload rồi
1208                }
1209
1210                // Mark as preloading
1211                videoPreloadCache.set(videoUrl, { status: 'loading', timestamp: Date.now() });
1212
1213                // Preload bằng cách tạo video element và load metadata
1214                const video = document.createElement('video');
1215                video.preload = 'metadata'; // Chỉ load metadata, không load toàn bộ video
1216                video.muted = true;
1217                video.playsInline = true;
1218                video.style.display = 'none';
1219
1220                video.addEventListener('loadedmetadata', function () {
1221                    videoPreloadCache.set(videoUrl, { status: 'loaded', timestamp: Date.now() });
1222                    document.body.removeChild(video);
1223                });
1224
1225                video.addEventListener('error', function () {
1226                    videoPreloadCache.set(videoUrl, { status: 'error', timestamp: Date.now() });
1227                    if (document.body.contains(video)) {
1228                        document.body.removeChild(video);
1229                    }
1230                });
1231
1232                video.src = videoUrl;
1233                document.body.appendChild(video);
1234
1235                // Cleanup cache sau 5 phút
1236                setTimeout(() => {
1237                    videoPreloadCache.delete(videoUrl);
1238                }, 5 * 60 * 1000);
1239            }
1240
1241            // Tối ưu: Cache match-list selector
1242            let matchListCache = null;
1243            function getMatchList() {
1244                if (!matchListCache) {
1245                    matchListCache = document.getElementById('match-list');
1246                }
1247                return matchListCache;
1248            }
1249
1250            // Hàm render toàn bộ trận đấu
1251            function renderAllMatches(matches) {
1252                const matchList = getMatchList();
1253                if (!matchList) {
1254                    console.error('Không tìm thấy phần tử match-list');
1255                    return;
1256                }
1257
1258                // Xóa danh sách cũ
1259                matchList.innerHTML = '';
1260
1261                // Render danh sách mới
1262                matches.forEach(match => {
1263                    if (!match || !match.data) return; // Bỏ qua match lỗi
1264
1265                    const cardHTML = createMatchCard(match);
1266                    if (!cardHTML) return; // Bỏ qua nếu không tạo được thẻ
1267                    
1268                    const tempDiv = document.createElement('div');
1269                    tempDiv.innerHTML = cardHTML.trim();
1270                    const cardElement = tempDiv.firstChild;
1271                    if (!cardElement) return;
1272
1273                    // Ẩn các trận không có bình luận viên
1274                    /*if (cardElement.getAttribute('data-blv') === 'false') {
1275                        cardElement.classList.add('d-none');
1276                    }*/
1277
1278                    // Tối ưu: Preload video metadata khi hover vào match card
1279                    if (match.data && match.data.videoUrl) {
1280                        let preloadTimeout = null;
1281                        cardElement.addEventListener('mouseenter', function () {
1282                            // Debounce: chỉ preload sau 500ms hover
1283                            preloadTimeout = setTimeout(() => {
1284                                preloadVideoMetadata(match.data.videoUrl);
1285                            }, 500);
1286                        });
1287                        cardElement.addEventListener('mouseleave', function () {
1288                            if (preloadTimeout) {
1289                                clearTimeout(preloadTimeout);
1290                                preloadTimeout = null;
1291                            }
1292                        });
1293                    }
1294
1295                    matchList.appendChild(cardElement);
1296                });
1297
1298                // Cập nhật bộ đếm
1299                const visibleMatches = document.querySelectorAll('.match-card:not(.d-none)');
1300                updateFilterCounts(visibleMatches, document.querySelectorAll('.match-card'));
1301            }
1302
1303            // Hàm lọc trận đấu
1304            function filterMatches(type, matches) {
1305                const allCards = document.querySelectorAll('.match-card');
1306
1307                // Lọc theo môn thể thao
1308                const sportFiltered = Array.from(allCards).filter(card => {
1309                    const sport = card.dataset.sport;
1310                    return currentFilters.sport === 'all' || sport === currentFilters.sport;
1311                });
1312
1313                let finalFiltered = sportFiltered;
1314
1315                // Áp dụng các bộ lọc khác
1316                if (currentFilters.live) {
1317                    finalFiltered = finalFiltered.filter(card => card.dataset.live === 'true' && card.dataset.blv === 'true');
1318                } else if (currentFilters.blv) {
1319                    finalFiltered = finalFiltered.filter(card => card.dataset.blv === 'false');
1320                } else if (currentFilters.hot) {
1321                    finalFiltered = finalFiltered.filter(card => card.dataset.hot === 'true' && card.dataset.blv === 'true');
1322                } else if (currentFilters.date !== 'all') {
1323                    finalFiltered = finalFiltered.filter(card => card.dataset.date === currentFilters.date && card.dataset.blv === 'true');
1324                }
1325
1326                // Hiển thị/ẩn các thẻ
1327                allCards.forEach(card => {
1328                    card.classList.toggle('d-none', !finalFiltered.includes(card));
1329                });
1330
1331                // Cập nhật bộ đếm
1332                if (type === 'parent') {
1333                    updateFilterCounts(sportFiltered, allCards);
1334                } else {
1335                    updateFilterCounts(finalFiltered, allCards);
1336                }
1337            }
1338
1339            // Gắn sự kiện cho nút lọc môn thể thao
1340            document.querySelectorAll('.sports-filter__button[data-sport]').forEach(button => {
1341                button.addEventListener('click', () => {
1342                    currentFilters.sport = button.getAttribute('data-sport');
1343                    filterMatches('parent');
1344                });
1345            });
1346
1347            // Gắn sự kiện cho nút lọc con
1348            document.querySelectorAll('.sports-filter__button_child').forEach(btn => {
1349                btn.addEventListener('click', function () {
1350                    const filterType = this.getAttribute('data-filter');
1351                    const value = this.getAttribute('data-value');
1352
1353                    if (filterType === 'date') {
1354                        currentFilters.date = value;
1355                        currentFilters.live = false;
1356                        currentFilters.hot = false;
1357                        currentFilters.blv = false;
1358                    } else if (filterType === 'live') {
1359                        currentFilters.live = true;
1360                        currentFilters.date = 'all';
1361                        currentFilters.hot = false;
1362                        currentFilters.blv = false;
1363                    } else if (filterType === 'hot') {
1364                        currentFilters.hot = true;
1365                        currentFilters.date = 'all';
1366                        currentFilters.live = false;
1367                        currentFilters.blv = false;
1368                    } else if (filterType === 'child_all') {
1369                        currentFilters.live = false;
1370                        currentFilters.hot = false;
1371                        currentFilters.blv = false;
1372                        currentFilters.date = 'all';
1373                    }
1374
1375                    document.querySelectorAll('.sports-filter__button_child').forEach(b => b.classList.remove('active'));
1376                    this.classList.add('active');
1377
1378                    filterMatches('child');
1379                });
1380            });
1381
1382            // Gắn sự kiện cho toggle livescore
1383            const liveToggle = document.getElementById('livescoreToggle');
1384            if (liveToggle) {
1385                liveToggle.addEventListener('change', () => {
1386                    currentFilters.live = liveToggle.checked;
1387                    filterMatches('parent');
1388                });
1389            }
1390
1391            // ===== WEBSOCKET INTEGRATION =====
1392            let wsClient = null;
1393            let matchesWebSocketConnected = false;
1394            let fallbackPollingInterval = null;
1395
1396            // Function để transform WebSocket data format
1397            function transformWebSocketMatches(data) {
1398                const newMatches = [];
1399
1400                for (const [key, matchData] of Object.entries(data)) {
1401                    // Logic tương tự như trong refreshMatches()
1402                    const anchorList = Array.isArray(matchData.anchorAppointmentVoList)
1403                        ? matchData.anchorAppointmentVoList
1404                        : [];
1405
1406                    if (anchorList[0]?.nickName === 'Live streaming') continue;
1407
1408                    const homeScoreArr = Array.isArray(matchData.homeScore) ? matchData.homeScore : [];
1409                    const awayScoreArr = Array.isArray(matchData.awayScore) ? matchData.awayScore : [];
1410                    const homeScore = homeScoreArr.length ? homeScoreArr[0] : 0;
1411                    const awayScore = awayScoreArr.length ? awayScoreArr[0] : 0;
1412
1413                    let slug = key;
1414                    if (matchData.house_id && matchData.house_id !== null) {
1415                        slug = `${key}?houseId=${matchData.house_id}`;
1416                    }
1417
1418                    const competitionName = matchData.competitionName || 'NBA';
1419                    const matchDataObj = {
1420                        id: 2,
1421                        slug: slug,
1422                        sport: sportName(matchData.sportId),
1423                        live: matchData.matchStatus === 2,
1424                        hot: true,
1425                        blv: anchorList[0]?.nickName !== 'Live streaming',
1426                        date: formatDate(fixtime(matchData.matchTime), 'd/m'),
1427                        datesearch: formatDate(fixtime(matchData.matchTime), 'Y-m-d'),
1428                        hour: formatDate(fixtime(matchData.matchTime), 'H:i'),
1429                        competitionName: competitionName,
1430                        teams: [
1431                            matchData.homeTeamName || 'Team C',
1432                            matchData.awayTeamName || 'Team D'
1433                        ],
1434                        score: `${homeScore}:${awayScore}`,
1435                        videoUrl: matchData.videoUrl || 'https://live2.example.com',
1436                        animationUrl: matchData.animationUrl || 'https://animation.example.com',
1437                        data: matchData
1438                    };
1439
1440                    newMatches.push(matchDataObj);
1441                }
1442
1443                return newMatches;
1444            }
1445
1446            // Function để init WebSocket
1447            function initMatchesWebSocket() {
1448                // WebSocket URL - có thể config từ PHP hoặc hardcode
1449                // Nếu có server-socket service, dùng URL đó
1450                // Format: wss://server.gvapi.cc hoặc ws://localhost:3320
1451                const wsUrl = 'wss://server.colahd.tv/ws'; // Thay bằng URL thực tế của bạn
1452
1453                // Check nếu RealtimeWebSocketClient đã được load
1454                if (typeof RealtimeWebSocketClient === 'undefined') {
1455                    console.warn('[Homepage] RealtimeWebSocketClient not loaded, falling back to polling');
1456                    startFallbackPolling();
1457                    return;
1458                }
1459
1460                wsClient = new RealtimeWebSocketClient(wsUrl);
1461
1462                // Subscribe to matches updates
1463                wsClient.subscribe('matches:updated', (data) => {
1464                    //console.log('[Homepage] Received matches update from WebSocket');
1465
1466                    if (data.code === '0000' && data.data) {
1467                        // Transform data để tương thích với renderAllMatches()
1468                        const transformedMatches = transformWebSocketMatches(data.data);
1469                        renderAllMatches(transformedMatches);
1470                        filterMatches('parent', transformedMatches);
1471                        saveMatchesToCache(transformedMatches); // 
1472                    } else if (data.data && typeof data.data === 'object') {
1473                        // Nếu data trực tiếp là object (không có code)
1474                        const transformedMatches = transformWebSocketMatches(data.data);
1475                        renderAllMatches(transformedMatches);
1476                        filterMatches('parent', transformedMatches);
1477                        saveMatchesToCache(transformedMatches); // 
1478                    }
1479                });
1480
1481                // Handle connection events
1482                wsClient.subscribe('connected', () => {
1483                    //console.log('[Homepage] WebSocket connected');
1484                    matchesWebSocketConnected = true;
1485                    // Stop fallback polling nếu đang chạy
1486                    if (fallbackPollingInterval) {
1487                        clearInterval(fallbackPollingInterval);
1488                        fallbackPollingInterval = null;
1489                    }
1490                });
1491
1492                wsClient.subscribe('disconnected', () => {
1493                    //console.log('[Homepage] WebSocket disconnected, falling back to polling');
1494                    matchesWebSocketConnected = false;
1495                    startFallbackPolling();
1496                });
1497
1498                wsClient.subscribe('error', (error) => {
1499                    console.error('[Homepage] WebSocket error:', error);
1500                    matchesWebSocketConnected = false;
1501                    startFallbackPolling();
1502                });
1503
1504                wsClient.connect();
1505            }
1506
1507            // Fallback polling nếu WebSocket fail
1508            function startFallbackPolling() {
1509                if (fallbackPollingInterval) return; // Already running
1510
1511                //('[Homepage] Starting fallback polling');
1512                fallbackPollingInterval = setInterval(() => {
1513                    if (!matchesWebSocketConnected) {
1514                        refreshMatches(); // Use existing function
1515                    } else {
1516                        // WebSocket reconnected, stop polling
1517                        clearInterval(fallbackPollingInterval);
1518                        fallbackPollingInterval = null;
1519                    }
1520                }, 120000); // 2 minutes như cũ
1521            }
1522
1523            // Nếu SSR đã render HTML, ta không cần nạp từ localStorage hay fetch API lần đầu nữa (tránh nháy màn hình)
1524            const ssrCardsCount = document.querySelectorAll('.match-card').length;
1525            
1526            if (ssrCardsCount === 0) {
1527                // Thử load từ cache trước nếu không có SSR
1528                const cachedMatches = loadMatchesFromCache();
1529                if (cachedMatches && cachedMatches.length > 0) {
1530                    try {
1531                        renderAllMatches(cachedMatches);
1532                        filterMatches('parent', cachedMatches);
1533                    } catch (error) {
1534                        console.error('[Cache Render Error]', error);
1535                    }
1536                }
1537
1538                // Fetch fresh data từ API (cập nhật + ghi đè cache)
1539                refreshMatches();
1540            }
1541
1542            // Thử WebSocket trước, fallback to polling nếu fail
1543            // Delay một chút để đảm bảo RealtimeWebSocketClient đã được load
1544            setTimeout(() => {
1545                initMatchesWebSocket();
1546            }, 500);
1547
1548            // Cleanup khi page unload
1549            window.addEventListener('beforeunload', () => {
1550                if (wsClient) {
1551                    wsClient.disconnect();
1552                }
1553                if (fallbackPollingInterval) {
1554                    clearInterval(fallbackPollingInterval);
1555                }
1556            });
1557        </script>
1557
1558            <style>
1559        .home-banner-slider {
1560            width: 100%;
1561            margin: 15px 0;
1562            border-radius: 8px;
1563            overflow: hidden;
1564            position: relative;
1565            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
1566            display: none;
1567            /* Hidden by default until loaded */
1568            z-index: 10;
1569        }
1570
1571        .home-banner-track {
1572            display: flex;
1573            transition: transform 0.5s ease-in-out;
1574            height: 100%;
1575        }
1576
1577        .home-banner-slide {
1578            min-width: 100%;
1579            display: block;
1580            text-decoration: none;
1581        }
1582
1583        .home-banner-slide img {
1584            width: 100%;
1585            height: auto;
1586            display: block;
1587            object-fit: cover;
1588        }
1589
1590        .home-banner-dots {
1591            position: absolute;
1592            bottom: 10px;
1593            left: 0;
1594            right: 0;
1595            display: flex;
1596            justify-content: center;
1597            gap: 6px;
1598        }
1599
1600        .home-banner-dot {
1601            width: 8px;
1602            height: 8px;
1603            background: rgba(255, 255, 255, 0.5);
1604            border-radius: 50%;
1605            cursor: pointer;
1606            transition: background 0.3s;
1607        }
1608
1609        .home-banner-dot.active {
1610            background: white;
1611            transform: scale(1.2);
1612        }
1613    </style>
1614    
1614<script>
1615        document.addEventListener('DOMContentLoaded', async function () {
1616            try {
1617                // Fetch settings
1618                const res = await fetch('https://api.gvapi.cc/api/settings');
1619                const data = await res.json();
1620
1621                if (data.success && data.home_banners && data.home_banners.length > 0) {
1622                    const banners = data.home_banners.sort((a, b) => a.order - b.order);
1623
1624                    // Create slider container
1625                    const sliderContainer = document.createElement('div');
1626                    sliderContainer.className = 'home-banner-slider';
1627
1628                    const track = document.createElement('div');
1629                    track.className = 'home-banner-track';
1630
1631                    const dotsContainer = document.createElement('div');
1632                    dotsContainer.className = 'home-banner-dots';
1633
1634                    banners.forEach((banner, index) => {
1635                        // Slide
1636                        const slide = document.createElement('a');
1637                        slide.className = 'home-banner-slide';
1638                        slide.href = banner.link_url && banner.link_url !== '#' ? banner.link_url : 'javascript:void(0)';
1639                        slide.target = banner.link_url && banner.link_url !== '#' ? '_blank' : '_self';
1640
1641                        const img = document.createElement('img');
1642                        img.src = banner.image_url;
1643                        img.alt = banner.name || 'Banner';
1644
1645                        slide.appendChild(img);
1646                        track.appendChild(slide);
1647
1648                        // Dot
1649                        const dot = document.createElement('div');
1650                        dot.className = 'home-banner-dot';
1651                        if (index === 0) dot.classList.add('active');
1652
1653                        dot.addEventListener('click', () => {
1654                            goToSlide(index);
1655                        });
1656
1657                        dotsContainer.appendChild(dot);
1658                    });
1659
1660                    sliderContainer.appendChild(track);
1661                    if (banners.length > 1) {
1662                        sliderContainer.appendChild(dotsContainer);
1663                    }
1664
1665                    // Inject into DOM (after h1 in hero content)
1666                    const h1 = document.querySelector('.hero__content h1');
1667                    if (h1) {
1668                        h1.insertAdjacentElement('afterend', sliderContainer);
1669                        sliderContainer.style.display = 'block';
1670
1671                        // Slider Logic
1672                        let currentIndex = 0;
1673                        let autoPlayInterval;
1674                        const totalSlides = banners.length;
1675
1676                        function goToSlide(index) {
1677                            if (totalSlides <= 1) return;
1678                            currentIndex = index;
1679                            track.style.transform = `translateX(-${currentIndex * 100}%)`;
1680
1681                            // Update dots
1682                            Array.from(dotsContainer.children).forEach((d, i) => {
1683                                if (i === currentIndex) d.classList.add('active');
1684                                else d.classList.remove('active');
1685                            });
1686
1687                            resetAutoPlay();
1688                        }
1689
1690                        function nextSlide() {
1691                            let next = currentIndex + 1;
1692                            if (next >= totalSlides) next = 0;
1693                            goToSlide(next);
1694                        }
1695
1696                        function resetAutoPlay() {
1697                            clearInterval(autoPlayInterval);
1698                            autoPlayInterval = setInterval(nextSlide, 3000);
1699                        }
1700
1701                        if (totalSlides > 1) {
1702                            resetAutoPlay();
1703                        }
1704                    }
1705                }
1706            } catch (err) {
1707                console.error('Lỗi load home banners:', err);
1708            }
1709        });
1710    </script>
1710
1711            <style>
1712            @media (min-width: 481px) and (max-width: 767px) {
1713                .match-card__status {
1714                    max-width: 120px;
1715                    font-size: 12px;
1716                }
1717            }
1718
1719            @media (min-width: 576px) and (max-width: 767px) {
1720                .match-card__league {
1721                    max-width: 100px;
1722                }
1723            }
1724
1725            @media (min-width: 481px) and (max-width: 575px) {
1726                .match-card__header {
1727                    flex-direction: row !important;
1728                }
1729
1730                .match-card__time {
1731                    max-width: 100px !important;
1732                }
1733            }
1734
1735            .top-live-box {
1736                width: 100%;
1737                height: auto;
1738                display: flex;
1739                gap: 8px;
1740            }
1741
1742            .top-live-box .left {
1743                width: 100%;
1744                min-height: 564px;
1745                background-color: #000;
1746                border-radius: 4px;
1747                overflow: hidden;
1748            }
1749
1750            .top-live-box .live-list {
1751                width: 240px;
1752                flex-shrink: 0;
1753            }
1754
1755            .top-live-box .live-list .live-item {
1756                width: 100%;
1757                height: 144px;
1758                margin-bottom: 6px;
1759                cursor: pointer;
1760                border-radius: 4px;
1761                transition: all .1s ease-in-out;
1762                overflow: hidden;
1763                border: 2px solid transparent;
1764                position: relative;
1765            }
1766
1767            .top-live-box .live-list .live-item .anchor-item {
1768                width: 100%;
1769                height: 100%;
1770            }
1771
1772            .el-image img {
1773                display: block;
1774                width: 100%;
1775                height: 100%;
1776                object-fit: cover;
1777            }
1778
1779            .btn-view-truc-tiep {
1780                position: absolute;
1781                top: 70%;
1782                left: 50%;
1783                transform: translate(-50%, -50%);
1784                z-index: 5;
1785                background: #f2152d;
1786                padding: 20px;
1787                border-radius: 30px;
1788                cursor: pointer;
1789                text-align: center;
1790            }
1791
1792            .btn-view-truc-tiep:hover {
1793                opacity: 0.8;
1794            }
1795
1796            .video-player {
1797                position: relative;
1798            }
1799
1800            .top-live-box .live-list .live-item.active {
1801                border: 2px solid #ff0202;
1802            }
1803
1804            .overlay-click {
1805                position: absolute;
1806                top: 0;
1807                left: 0;
1808                width: 100%;
1809                height: 100%;
1810                z-index: 10;
1811                display: block;
1812            }
1813
1814            /* Responsive */
1815            @media screen and (max-width: 1024px) {
1816                .top-live-box {
1817                    flex-direction: column;
1818                }
1819
1820                .top-live-box .left {
1821                    width: 100%;
1822                    min-height: 400px;
1823                }
1824
1825                .top-live-box .live-list {
1826                    display: none !important;
1827                    width: 100%;
1828                    flex-direction: row;
1829                    flex-wrap: wrap;
1830                    justify-content: center;
1831                    gap: 6px;
1832                    margin-top: 12px;
1833                }
1834
1835                .top-live-box .live-list .live-item {
1836                    width: calc(50% - 6px);
1837                    height: 120px;
1838                }
1839            }
1840
1841            @media screen and (max-width: 768px) {
1842                .top-live-box .left {
1843                    min-height: unset;
1844                }
1845
1846                .btn-view-truc-tiep {
1847                    padding: 10px 10px;
1848                    font-size: 12px;
1849                }
1850
1851                .top-live-box .live-list .live-item {
1852                    width: calc(50% - 3px);
1853                    height: 100px;
1854                }
1855            }
1856
1857            @media screen and (max-width: 480px) {
1858                .top-live-box .live-list .live-item {
1859                    width: calc(50% - 3px);
1860                    height: 100px;
1861                }
1862
1863                .btn-view-truc-tiep {
1864                    padding: 8px 14px;
1865                    font-size: 13px;
1866                }
1867
1868                .match-card__body {
1869                    gap: 0.6rem;
1870                }
1871            }
1872        </style>
1873        
1873<script src="//unpkg.byted-static.com/xgplayer/3.0.0-next.1/dist/index.min.js"></script>
1873
1874        
1874<script src="//unpkg.com/[email protected]/dist/index.min.js"></script>
1874
1875        <link rel="stylesheet" href="//unpkg.byted-static.com/xgplayer/3.0.0-alpha.100/dist/xgplayer.min.css" />
1876        
1876<script type="text/javascript">
1877            // Hàm lấy domain API random cho video-home (pinned-home)
1878            function getVideoHomeApiDomain() {
1879                const domains = [
1880                    'video-home.gvapi.cc'
1881                ];
1882
1883                // Random chọn một domain
1884                const index = Math.floor(Math.random() * domains.length);
1885                const selected = domains[index];
1886
1887                return 'https://' + selected;
1888            }
1889
1890            document.addEventListener('DOMContentLoaded', function () {
1891                const apiBase = getVideoHomeApiDomain();
1892                const STORAGE_KEY = 'pinnedMatchesCache';
1893                const heroSection = document.querySelector('section.hero');
1894                if (!heroSection) {
1895                    console.error('Hero section not found.');
1896                    return;
1897                }
1898
1899                const skeletonHtml = `
1900                    <div class="top-live-box container skeleton-loading" id="pinned-matches-container">
1901                        <style>
1902                            .skeleton-box {
1903                                display: inline-block;
1904                                height: 100%;
1905                                width: 100%;
1906                                position: relative;
1907                                overflow: hidden;
1908                                background-color: #2a2a2a;
1909                                border-radius: 8px;
1910                            }
1911                            .skeleton-box::after {
1912                                position: absolute;
1913                                top: 0;
1914                                right: 0;
1915                                bottom: 0;
1916                                left: 0;
1917                                transform: translateX(-100%);
1918                                background-image: linear-gradient(
1919                                    90deg,
1920                                    rgba(255, 255, 255, 0) 0,
1921                                    rgba(255, 255, 255, 0.05) 20%,
1922                                    rgba(255, 255, 255, 0.2) 60%,
1923                                    rgba(255, 255, 255, 0)
1924                                );
1925                                animation: shimmer 2s infinite;
1926                                content: '';
1927                            }
1928                            @keyframes shimmer { 100% { transform: translateX(100%); } }
1929                            .skeleton-loading .left { aspect-ratio: 16/9; background: #1a1a1a; padding: 10px; border-radius: 8px;}
1930                            .skeleton-loading .live-list { display: flex; gap: 10px; margin-top: 10px; }
1931                            .skeleton-loading .live-item { flex: 1; aspect-ratio: 1/1; background: #1a1a1a; border-radius: 8px; overflow: hidden; }
1932                        </style>
1933                        <div class="left">
1934                            <div class="skeleton-box" style="min-height: 300px;"></div>
1935                        </div>
1936                        <div class="live-list">
1937                            <div class="live-item"><div class="skeleton-box"></div></div>
1938                            <div class="live-item"><div class="skeleton-box"></div></div>
1939                            <div class="live-item"><div class="skeleton-box"></div></div>
1940                            <div class="live-item"><div class="skeleton-box"></div></div>
1941                        </div>
1942                    </div>
1943                `;
1944
1945                function renderMatches(matches) {
1946                    const anchors = matches.slice(0, 4).map((match, index) => ({
1947                        streamUrl: match.playStreamAddress2,
1948                        image: match.houseImage,
1949                        name: match.nickName,
1950                        slug: match.slugKey + '?houseId=' + match.houseId
1951                    }));
1952
1953                    if (anchors.length === 0) return;
1954
1955                    const streamUrl = anchors[0].streamUrl;
1956
1957                    const liveBoxHtml = `
1958                        <div class="top-live-box container" id="pinned-matches-container">
1959                            <div class="left">
1960                                <div class="video-container">
1961                                    <div class="video-player">
1962                                        <div id="mse" style="width: 100%;"></div>
1963                                        <a href="/truc-tiep/${anchors[0].slug}" class="overlay-click" id="btn-view-link" rel="nofollow"></a>
1964                                        <span class="btn-view-truc-tiep" rel="nofollow">Vào phòng live đang phát sóng</span>
1965                                    </div>
1966                                </div>
1967                            </div>
1968                            <div class="live-list">
1969                                ${anchors.map((anchor, index) => `
1970                                    <div class="live-item ${index === 0 ? 'active' : ''} live-living-item" data-index="${index}">
1971                                        <div class="anchor-item">
1972                                            <div class="placeholder img">
1973                                                <img src="${anchor.image}" alt="${anchor.name}" style="object-fit: cover;">
1974                                            </div>
1975                                        </div>
1976                                    </div>
1977                                `).join('')}
1978                            </div>
1979                        </div>
1980                    `;
1981
1982                    const existingContainer = document.getElementById('pinned-matches-container');
1983                    if (existingContainer) {
1984                        existingContainer.outerHTML = liveBoxHtml;
1985                    } else {
1986                        heroSection.insertAdjacentHTML('afterend', liveBoxHtml);
1987                    }
1988
1989                    if (window.Player && window.HlsPlayer) {
1990                        new Player({
1991                            plugins: [window.HlsPlayer],
1992                            id: "mse",
1993                            ignores: ["time", "progress"],
1994                            autoplayMuted: true,
1995                            autoplay: true,
1996                            playsinline: true,
1997                            isLive: true,
1998                            fluid: true,
1999                            pip: true,
2000                            muted: true,
2001                            url: streamUrl
2002                        });
2003                    }
2004
2005                    const liveItems = document.querySelectorAll('#pinned-matches-container .live-item');
2006                    const viewLink = document.getElementById('btn-view-link');
2007
2008                    liveItems.forEach(item => {
2009                        item.addEventListener('click', () => {
2010                            const index = parseInt(item.getAttribute('data-index'));
2011                            liveItems.forEach(i => i.classList.remove('active'));
2012                            item.classList.add('active');
2013
2014                            if (window.Player && window.HlsPlayer) {
2015                                new Player({
2016                                    plugins: [window.HlsPlayer],
2017                                    id: "mse",
2018                                    ignores: ["time", "progress"],
2019                                    autoplayMuted: true,
2020                                    autoplay: true,
2021                                    playsinline: true,
2022                                    isLive: true,
2023                                    fluid: true,
2024                                    pip: true,
2025                                    muted: true,
2026                                    url: anchors[index].streamUrl
2027                                });
2028                            }
2029                            if (viewLink) {
2030                                viewLink.href = '/truc-tiep/' + anchors[index].slug;
2031                            }
2032                        });
2033                    });
2034                }
2035
2036                let hasLocalData = false;
2037                try {
2038                    const cached = localStorage.getItem(STORAGE_KEY);
2039                    if (cached) {
2040                        const parsed = JSON.parse(cached);
2041                        if (parsed && parsed.length > 0) {
2042                            renderMatches(parsed);
2043                            hasLocalData = true;
2044                        }
2045                    }
2046                } catch (e) {
2047                    console.error('Error parsing localStorage:', e);
2048                }
2049
2050                if (!hasLocalData) {
2051                    heroSection.insertAdjacentHTML('afterend', skeletonHtml);
2052                }
2053
2054                fetch('https://video-home.gvapi.cc/api/pinned-home?t=' + new Date().getTime())
2055                    .then(response => {
2056                        if (!response.ok) throw new Error('API Response not ok: ' + response.status);
2057                        return response.json();
2058                    })
2059                    .then(data => {
2060                        const matches = data.pinnedMatches;
2061                        if (!matches || matches.length < 1) {
2062                            if (!hasLocalData) {
2063                                const existingContainer = document.getElementById('pinned-matches-container');
2064                                if (existingContainer) existingContainer.remove();
2065                            }
2066                            return;
2067                        }
2068                        localStorage.setItem(STORAGE_KEY, JSON.stringify(matches));
2069                        renderMatches(matches);
2070                    })
2071                    .catch(error => {
2072                        console.error('Error fetching API data:', error);
2073                        if (!hasLocalData) {
2074                            const existingContainer = document.getElementById('pinned-matches-container');
2075                            if (existingContainer) existingContainer.remove();
2076                        }
2077                    });
2078            });
2079        </script>
2079
2080
2081            <style>
2082        .aligncenter {
2083            margin: 0 auto;
2084
2085        }
2086
2087        .wp-caption {
2088            max-width: 100%;
2089        }
2090
2091        footer .container {
2092            grid-template-columns: 1fr;
2093        }
2094    </style>
2095        
2095<script>
2096        const mini = document.querySelector('.video-player.is-floating.floating-draggable');
2097        const margin = 8; // cách mép
2098
2099        function clampFloatingVideo() {
2100            if (!mini) return;
2101
2102            const rect = mini.getBoundingClientRect();
2103
2104            let x = rect.left;
2105            let y = rect.top;
2106
2107            const vw = window.innerWidth;
2108            const vh = window.innerHeight;
2109
2110            const minX = margin;
2111            const minY = margin;           // nếu muốn chừa notch: + safeTop
2112            const maxX = vw - rect.width - margin;
2113            const maxY = vh - rect.height - margin;
2114
2115            if (x < minX) x = minX;
2116            if (x > maxX) x = maxX;
2117            if (y < minY) y = minY;
2118            if (y > maxY) y = maxY;
2119
2120            mini.style.left = x + 'px';
2121            mini.style.top = y + 'px';
2122        }
2123
2124        // chạy lại mỗi khi viewport thay đổi
2125        window.addEventListener('scroll', clampFloatingVideo);
2126        window.addEventListener('resize', clampFloatingVideo);
2127        window.addEventListener('orientationchange', clampFloatingVideo);
2128
2129        // iOS Safari thanh URL co giãn → nên dùng thêm:
2130        if (window.visualViewport) {
2131            visualViewport.addEventListener('resize', clampFloatingVideo);
2132            visualViewport.addEventListener('scroll', clampFloatingVideo);
2133        }
2134    </script>
2134
2135
2136        
2136<script>
2137        // === Catfish Banner Global: lấy từ API /api/catfish-banners (giống React CatfishBanners.jsx) ===
2138        (function () {
2139            var apiUrl = 'https://api.gvapi.cc/api/catfish-banners';
2140            fetch(apiUrl)
2141                .then(function (res) { return res.ok ? res.json() : null; })
2142                .then(function (data) {
2143                    if (!data || !data.success || !data.data || !data.data.length) return;
2144
2145                    // === Video catfish overlay (nếu có trong trang watch) ===
2146                    var catfishLink = data.data[0].link_url || '';
2147                    if (catfishLink) {
2148                        var overlayTop = document.querySelector('.video-catfish-overlay-top');
2149                        var overlayBottom = document.querySelector('.video-catfish-overlay');
2150                        if (overlayTop) {
2151                            overlayTop.href = catfishLink;
2152                            overlayTop.style.display = 'block';
2153                        }
2154                        if (overlayBottom) {
2155                            overlayBottom.href = catfishLink;
2156                            overlayBottom.style.display = 'block';
2157                        }
2158                    }
2159
2160                    // === Tạo container catfish-banner-global (fixed bottom, giống React) ===
2161                    var wrapper = document.createElement('div');
2162                    wrapper.className = 'catfish-banner-global';
2163                    wrapper.style.cssText = 'position:fixed;bottom:0;left:0;right:0;z-index:9999;display:flex;flex-direction:column;align-items:center;pointer-events:none;width:50%;margin:0 auto;';
2164
2165                    // Nút đóng
2166                    var closeBtn = document.createElement('button');
2167                    closeBtn.className = 'catfish-banner-close';
2168                    closeBtn.innerHTML = '✕';
2169                    closeBtn.setAttribute('aria-label', 'Đóng quảng cáo');
2170                    closeBtn.style.cssText = 'position:absolute;top:-24px;right:4px;width:24px;height:24px;background:rgba(0,0,0,0.7);color:#fff;border:none;border-radius:50%;font-size:14px;line-height:24px;text-align:center;cursor:pointer;pointer-events:auto;z-index:10000;padding:0;';
2171                    closeBtn.addEventListener('click', function () { wrapper.remove(); });
2172                    wrapper.appendChild(closeBtn);
2173
2174                    // Render banners
2175                    data.data.forEach(function (banner) {
2176                        var a = document.createElement('a');
2177                        a.className = 'catfish-banner-global-item';
2178                        a.href = banner.link_url || '#';
2179                        a.target = '_blank';
2180                        a.rel = 'nofollow noopener noreferrer';
2181                        a.style.cssText = 'display:block;width:100%;pointer-events:auto;line-height:0;cursor:pointer;';
2182                        var img = document.createElement('img');
2183                        img.src = banner.image_url;
2184                        img.alt = banner.name || 'Banner';
2185                        img.style.cssText = 'width:100%;height:auto;display:block;object-fit:contain;';
2186                        a.appendChild(img);
2187                        wrapper.appendChild(a);
2188                    });
2189
2190                    document.body.appendChild(wrapper);
2191
2192                    // Mobile: full width
2193                    var mq = window.matchMedia('(max-width: 768px)');
2194                    function applyMobile(e) { wrapper.style.width = e.matches ? '100%' : '50%'; }
2195                    applyMobile(mq);
2196                    mq.addListener(applyMobile);
2197                })
2198                .catch(function (e) { console.warn('Catfish banner load failed:', e); });
2199        })();
2200    </script>
2200
2201    
2201<script>
2202        // === FIX: Chặn smooth-scroll handlers can thiệp vào catfish overlay ===
2203        (function () {
2204            document.addEventListener('click', function (e) {
2205                var overlay = e.target.closest('.video-catfish-overlay, .video-catfish-overlay-top');
2206                if (!overlay) return;
2207                var href = overlay.getAttribute('href');
2208                if (href && href !== '#' && !href.startsWith('#')) {
2209                    e.stopImmediatePropagation();
2210                }
2211            }, true);
2212        })();
2213    </script>
2213
2214        
2214<script>
2215    document.addEventListener("DOMContentLoaded", function () {
2216        const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT, null, false);
2217        while (walker.nextNode()) {
2218            const node = walker.currentNode;
2219            if (node.nodeValue.match(/vô địch quốc gia/i)) {
2220                node.nodeValue = node.nodeValue.replace(/vô địch quốc gia/gi, "VĐQG");
2221            }
2222        }
2223    });
2224    </script>
2224
2225    
2226</html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.