{
    "ready": true,
    "site": {
        "id": 0,
        "domain": "drag13.io",
        "display_name": "Drag13 programmer's blog",
        "primary_country_code": "",
        "category_name": "Personal"
    },
    "metrics": {
        "global_rank": 3362753,
        "country_rank": 1143336,
        "category_rank": 538040,
        "daily_pageviews_per_visitor": 4.68,
        "daily_time_on_site_seconds": 423,
        "bounce_rate": 22.9,
        "search_visits_percent": 39.75,
        "total_sites_linking_in": 1,
        "monthly_unique_visitors": 235,
        "recorded_at": "2026-04-03 22:12:27"
    },
    "audit": {
        "score": 99
    },
    "traffic_sources": {
        "direct_percent": 28.75,
        "search_percent": 33.91,
        "social_percent": 10.35,
        "referral_percent": 12.21,
        "email_percent": 6.05,
        "paid_percent": 8.73
    },
    "seo_profile": {
        "backlinks_total": 1,
        "referring_domains": 1,
        "dofollow_backlinks_percent": 100,
        "organic_keywords": 33,
        "indexed_pages": 35,
        "page_speed_score": 100,
        "mobile_friendliness_score": 93,
        "authority_score": 29,
        "spam_risk_score": 27
    },
    "crawl_report": {
        "robots_status": 200,
        "sitemap_status": 200,
        "sitemap_total_urls": 35,
        "crawl_blocked": false,
        "crawl_blocked_by": "",
        "crawl_blocked_reason": "",
        "notes": [],
        "created_at": "2026-04-03 22:12:27"
    },
    "keywords": [
        {
            "keyword": "Drag13 programmer's blog",
            "position": 25,
            "search_engine": "Estimated",
            "checked_at": "2026-06-25 07:02:34",
            "is_estimated": true
        },
        {
            "keyword": "Drag13 programmer's blog personal",
            "position": 27,
            "search_engine": "Estimated",
            "checked_at": "2026-06-25 07:02:34",
            "is_estimated": true
        },
        {
            "keyword": "Drag13 programmer's blog reviews",
            "position": 29,
            "search_engine": "Estimated",
            "checked_at": "2026-06-25 07:02:34",
            "is_estimated": true
        },
        {
            "keyword": "drag13",
            "position": 31,
            "search_engine": "Estimated",
            "checked_at": "2026-06-25 07:02:34",
            "is_estimated": true
        },
        {
            "keyword": "programmer",
            "position": 33,
            "search_engine": "Estimated",
            "checked_at": "2026-06-25 07:02:34",
            "is_estimated": true
        },
        {
            "keyword": "blog",
            "position": 35,
            "search_engine": "Estimated",
            "checked_at": "2026-06-25 07:02:34",
            "is_estimated": true
        },
        {
            "keyword": "dev",
            "position": 37,
            "search_engine": "Estimated",
            "checked_at": "2026-06-25 07:02:34",
            "is_estimated": true
        },
        {
            "keyword": "javascript",
            "position": 39,
            "search_engine": "Estimated",
            "checked_at": "2026-06-25 07:02:34",
            "is_estimated": true
        }
    ],
    "rating": {
        "overall": 48,
        "label": "Average",
        "breakdown": [
            {
                "label": "Technical foundation",
                "score": 18,
                "max": 18
            },
            {
                "label": "Authority & trust",
                "score": 9,
                "max": 30
            },
            {
                "label": "Reach & market presence",
                "score": 3,
                "max": 18
            },
            {
                "label": "Search visibility",
                "score": 2,
                "max": 12
            },
            {
                "label": "Engagement & retention",
                "score": 9,
                "max": 10
            },
            {
                "label": "Channels & diversification",
                "score": 5,
                "max": 6
            },
            {
                "label": "Registry stability",
                "score": 3,
                "max": 6
            },
            {
                "label": "Quality system",
                "score": 100,
                "max": 100
            },
            {
                "label": "Reputation system",
                "score": 38,
                "max": 100
            },
            {
                "label": "Safety system",
                "score": 100,
                "max": 100
            },
            {
                "label": "Evidence confidence",
                "score": 100,
                "max": 100
            }
        ],
        "authority_score": 29,
        "quality_score": 100,
        "reputation_score": 38,
        "safety_score": 100,
        "confidence_score": 100,
        "fraud_score": 0,
        "authority_signals": {
            "backlinks": 1,
            "referring_domains": 1,
            "organic_keywords": 33,
            "indexed_pages": 35,
            "monthly_visitors": 235,
            "global_rank": 3362753,
            "engagement_score": 90,
            "crawl_quality_score": 100,
            "brand_completeness_score": 83,
            "link_diversity_score": 92,
            "technical_reliability_score": 98,
            "whois_score": 45,
            "whois_age_years": 0,
            "whois_stability_score": 100,
            "spam_penalty": 0
        },
        "whois_signals": {
            "age_years": 0,
            "days_to_expiry": null,
            "days_since_last_registry_update": null,
            "stability_score": 100,
            "registrar_changes": 0,
            "ownership_changes": 0,
            "nameserver_changes": 0,
            "status_changes": 0,
            "history_entries": 1,
            "privacy_protected": false,
            "dnssec_enabled": false,
            "has_registrant_country": false,
            "registrant_country": "",
            "nameserver_count": 0,
            "status_count": 0
        }
    },
    "community_ratings": {
        "votes": [],
        "recent_notes": [],
        "positive_weight": 0,
        "negative_weight": 0,
        "positive_count": 0,
        "negative_count": 0,
        "authenticated_count": 0,
        "anonymous_count": 0,
        "community_delta": 0,
        "community_score": 50,
        "confidence_score": 0,
        "notice": null,
        "positive_notice": false,
        "negative_notice": false,
        "neutral_count": 0,
        "total_votes": 0
    },
    "authority_score": 29,
    "trust_score": 67,
    "domain_tags": {
        "primary_tag": "",
        "primary_tag_score": 80,
        "primary_candidate": "T",
        "primary_candidate_score": 80,
        "tag_codes": "",
        "tags": [],
        "tag_breakdown": [
            {
                "code": "T",
                "label": "Trusted",
                "tone": "good",
                "description": "Strong trust, stability, and low-risk signals were detected.",
                "reason": "Low spam indicators plus strong trust, quality, registry, and stability signals were detected.",
                "message": "The site shows a reasonably trustworthy and stable profile.",
                "priority": 80,
                "score": 80,
                "match_percent": 80,
                "threshold_band": "strong"
            },
            {
                "code": "Infra",
                "label": "Risky infrastructure",
                "tone": "caution",
                "description": "The hosting / registrar / nameserver neighbourhood looks unusually risky.",
                "reason": "The infrastructure neighbourhood looks riskier than normal.",
                "message": "Infrastructure risk does not currently stand out.",
                "priority": 1,
                "score": 1,
                "match_percent": 1,
                "threshold_band": "none"
            },
            {
                "code": "Billing",
                "label": "Deceptive billing risk",
                "tone": "scam",
                "description": "Subscription, renewal, charge, or cancellation-abuse signals were detected.",
                "reason": "Subscription, renewal, charge, or cancellation-risk signals were detected.",
                "message": "No meaningful deceptive-billing signals were detected.",
                "priority": 0,
                "score": 0,
                "match_percent": 0,
                "threshold_band": "none"
            },
            {
                "code": "C",
                "label": "Caution",
                "tone": "caution",
                "description": "Signals are mixed or weak, so this domain should be treated carefully.",
                "reason": "Review carefully: mixed trust signals.",
                "message": "The current crawl does not show a meaningful caution match.",
                "priority": 0,
                "score": 0,
                "match_percent": 0,
                "threshold_band": "none"
            },
            {
                "code": "Crypto",
                "label": "Crypto drainer risk",
                "tone": "toxic",
                "description": "Wallet-connect or seed-phrase theft patterns were detected.",
                "reason": "Wallet-connect or seed-phrase theft patterns were detected.",
                "message": "No meaningful crypto-drainer signals were detected.",
                "priority": 0,
                "score": 0,
                "match_percent": 0,
                "threshold_band": "none"
            }
        ],
        "nsfw_score": 0,
        "trust_score": 68,
        "manual": {
            "has_changes": false,
            "verified_status": "",
            "tag_codes": "",
            "rating_delta": 0,
            "authority_delta": 0,
            "trust_delta": 0,
            "note": "",
            "adjusted_by": 0,
            "adjusted_at": "",
            "lock_scores": false,
            "lock_flags": false
        },
        "summary": "No public risk or trust tag is currently supported by the calibrated evidence.",
        "external_intel": [],
        "external_decision": [],
        "signal_scores": [
            {
                "label": "Strongest tag heuristic",
                "value": "T - 80%",
                "tone": "good",
                "detail": "The highest raw tag match from the heuristic engine before visibility thresholds and manual overrides."
            },
            {
                "label": "Trust score",
                "value": "68/100",
                "tone": "caution",
                "detail": "Confidence derived from authority, crawl quality, stability, and risk signals."
            },
            {
                "label": "Authority score",
                "value": "29/100",
                "tone": "spam",
                "detail": "A higher authority score usually means broader reputation and backlink confidence."
            },
            {
                "label": "Spam risk",
                "value": "0/100",
                "tone": "good",
                "detail": "Lower is better. This blends spam indicators with false-positive protections for legitimate sites."
            },
            {
                "label": "Quality score",
                "value": "100/100",
                "tone": "good",
                "detail": "Based on crawl quality, content completeness, and technical evidence."
            },
            {
                "label": "Safety score",
                "value": "100/100",
                "tone": "good",
                "detail": "Higher is safer. Direct fraud signals can heavily cap this even when SEO signals look strong."
            },
            {
                "label": "Fraud score",
                "value": "0/100",
                "tone": "good",
                "detail": "Lower is better. This reflects phishing, drainer, fake-support, fake-shop, and malware signals."
            },
            {
                "label": "Infrastructure risk",
                "value": "1/100",
                "tone": "good",
                "detail": "Lower is better. This reflects the IP, registrar, and nameserver neighbourhood seen by the crawler."
            },
            {
                "label": "Evidence confidence",
                "value": "100/100",
                "tone": "good",
                "detail": "Higher means the crawler had enough pages and registry evidence to make a stronger call."
            },
            {
                "label": "External evidence",
                "value": "Low",
                "tone": "unknown",
                "detail": "Quality of the structured search and review evidence cluster."
            },
            {
                "label": "External decision",
                "value": "Inconclusive",
                "tone": "unknown",
                "detail": "How third-party evidence compares with the current candidate tag."
            },
            {
                "label": "NSFW score",
                "value": "0/100",
                "tone": "good",
                "detail": "Context-aware adult-content detection with medical / educational false-positive reduction."
            },
            {
                "label": "Registry stability",
                "value": "100/100",
                "tone": "good",
                "detail": "Based on age, expiry runway, and the amount of ownership / registrar churn."
            }
        ],
        "signal_sections": [
            {
                "title": "Registry & ownership",
                "items": [
                    {
                        "label": "Domain age",
                        "value": "-",
                        "tone": "unknown",
                        "detail": "Older domains generally carry more historical trust than very new ones."
                    },
                    {
                        "label": "Stability score",
                        "value": "100/100",
                        "tone": "good",
                        "detail": "Penalised by registrar, ownership, and nameserver churn."
                    },
                    {
                        "label": "Days to expiry",
                        "value": "-",
                        "tone": "unknown",
                        "detail": "Very short renewal windows can be a weak trust signal."
                    },
                    {
                        "label": "Registrar / ownership changes",
                        "value": "0 / 0",
                        "tone": "good",
                        "detail": "Frequent ownership churn can weaken trust."
                    },
                    {
                        "label": "Nameserver changes",
                        "value": "0",
                        "tone": "good",
                        "detail": "Repeated infrastructure changes can indicate instability."
                    },
                    {
                        "label": "DNSSEC / privacy",
                        "value": "DNSSEC off - privacy off",
                        "tone": "caution",
                        "detail": "DNSSEC strengthens DNS trust; privacy is neutral on its own."
                    }
                ]
            },
            {
                "title": "Reputation & search evidence",
                "items": [
                    {
                        "label": "Backlinks",
                        "value": "1",
                        "tone": "unknown",
                        "detail": "Broader backlink evidence usually improves confidence."
                    },
                    {
                        "label": "Referring domains",
                        "value": "1",
                        "tone": "unknown",
                        "detail": "Unique linking domains are more useful than raw link volume."
                    },
                    {
                        "label": "Organic keywords",
                        "value": "33",
                        "tone": "caution",
                        "detail": "Search footprint helps distinguish real sites from thin shells."
                    },
                    {
                        "label": "Indexed pages",
                        "value": "35",
                        "tone": "caution",
                        "detail": "Larger index coverage usually means more evidence to classify from."
                    },
                    {
                        "label": "Brand strength",
                        "value": "83/100",
                        "tone": "good",
                        "detail": "Stronger brand signals reduce false positives for legitimate sites."
                    },
                    {
                        "label": "Risk label",
                        "value": "GOOD",
                        "tone": "unknown",
                        "detail": "This is the raw crawl / heuristic risk label feeding the tag model."
                    }
                ]
            },
            {
                "title": "Crawl, content & technicals",
                "items": [
                    {
                        "label": "HTTP status",
                        "value": "200",
                        "tone": "good",
                        "detail": "Healthy responses make classification more reliable."
                    },
                    {
                        "label": "HTTPS / speed",
                        "value": "HTTPS OK - 148 ms",
                        "tone": "good",
                        "detail": "Slow or broken technical signals weaken confidence."
                    },
                    {
                        "label": "Content words",
                        "value": "1,348",
                        "tone": "good",
                        "detail": "Thin pages are harder to trust and easier to manipulate."
                    },
                    {
                        "label": "Schema / structure",
                        "value": "0 schema - meta - H1",
                        "tone": "caution",
                        "detail": "Structured markup and basic on-page hygiene improve quality confidence."
                    },
                    {
                        "label": "Links on page",
                        "value": "28 internal - 4 external",
                        "tone": "good",
                        "detail": "Link patterns help detect thin directories and promo pages."
                    },
                    {
                        "label": "Page speed / mobile",
                        "value": "100/100 - 93/100",
                        "tone": "good",
                        "detail": "Better technical quality generally reduces low-effort site patterns."
                    },
                    {
                        "label": "Crawl access",
                        "value": "Open",
                        "tone": "good",
                        "detail": "The crawler reached the site without an anti-bot challenge."
                    }
                ]
            },
            {
                "title": "External evidence & explainability",
                "items": [
                    {
                        "label": "Decision state",
                        "value": "Inconclusive",
                        "tone": "unknown",
                        "detail": "Structured third-party evidence is still too thin, mixed, or unqualified to force a harder verdict."
                    },
                    {
                        "label": "Evidence quality",
                        "value": "Low",
                        "tone": "unknown",
                        "detail": "Blends source trust, domain matching, evidence diversity, and freshness."
                    },
                    {
                        "label": "Support vs contradiction",
                        "value": "0 / 0",
                        "tone": "unknown",
                        "detail": "Compares how much structured external evidence supports the candidate tag against evidence that contradicts it."
                    },
                    {
                        "label": "Qualified risk sources",
                        "value": "No",
                        "tone": "good",
                        "detail": "Risk tags only promote from external evidence when source diversity or source trust thresholds are met."
                    },
                    {
                        "label": "Uncertainty buffer",
                        "value": "Clear",
                        "tone": "good",
                        "detail": "Prevents thin or mixed external evidence from forcing a stronger tag than the evidence can justify."
                    }
                ]
            }
        ],
        "positives": [
            "Low registrar / ownership churn with solid registry stability.",
            "Healthy crawl quality and on-page completeness."
        ],
        "risks": []
    },
    "traffic_confidence": 48,
    "whois": {
        "current": {
            "id": 39313,
            "domain": "drag13.io",
            "source_type": "whois_text",
            "rdap_url": "",
            "registrar_name": "",
            "registrar_handle": "",
            "registrant_name": "",
            "registrant_org": "",
            "registrant_country": "",
            "registrant_email": "",
            "abuse_email": "",
            "created_date": null,
            "updated_date": null,
            "expires_date": null,
            "nameservers_json": "[]",
            "status_json": "[]",
            "dnssec": "unknown",
            "privacy_protected": 0,
            "content_hash": "f7e17c57c5fdd24df1793ece6bff99716369356b90b29c4725ac3ba12a76b72c",
            "history_count": 1,
            "last_checked_at": "2026-04-03 22:12:26",
            "last_changed_at": "2026-03-19 17:35:50",
            "created_at": "2026-03-19 17:35:50",
            "updated_at": "2026-04-03 22:12:26"
        },
        "history": [
            {
                "id": 40178,
                "domain": "drag13.io",
                "source_type": "whois_text",
                "registrar_name": "",
                "registrar_handle": "",
                "registrant_name": "",
                "registrant_org": "",
                "registrant_country": "",
                "registrant_email": "",
                "abuse_email": "",
                "created_date": null,
                "updated_date": null,
                "expires_date": null,
                "nameservers_json": "[]",
                "status_json": "[]",
                "dnssec": "unknown",
                "privacy_protected": 0,
                "content_hash": "f7e17c57c5fdd24df1793ece6bff99716369356b90b29c4725ac3ba12a76b72c",
                "checked_at": "2026-03-19 17:35:50",
                "change_summary": "Initial WHOIS snapshot captured.",
                "created_at": "2026-03-19 17:35:50"
            }
        ],
        "signals": {
            "age_years": 0,
            "days_to_expiry": null,
            "days_since_last_registry_update": null,
            "stability_score": 100,
            "registrar_changes": 0,
            "ownership_changes": 0,
            "nameserver_changes": 0,
            "status_changes": 0,
            "history_entries": 1,
            "privacy_protected": false,
            "dnssec_enabled": false,
            "has_registrant_country": false,
            "registrant_country": "",
            "nameserver_count": 0,
            "status_count": 0
        }
    },
    "discovered_domain": {
        "id": 68579,
        "domain": "drag13.io",
        "first_seen_at": "2026-03-15 18:57:01",
        "last_crawled_at": "2026-04-03 22:12:27",
        "last_title": "Drag13 Dev Blog - JavaScript, Performance, Security",
        "last_http_status": 200,
        "discovered_from_domain": "250kb.club",
        "depth": 0,
        "backlinks_count": 1,
        "rating_cache": 48,
        "spam_score": 34,
        "risk_label": "good",
        "category_name": "Personal",
        "primary_country_code": "",
        "internal_links_count": 28,
        "external_links_count": 4,
        "social_profiles_count": 3,
        "content_word_count": 1348,
        "title_quality_score": 93,
        "has_meta_description": 1,
        "has_h1": 1,
        "language_code": "en",
        "response_time_ms": 148,
        "robots_status": 200,
        "sitemap_status": 200,
        "sitemap_total_urls": 35,
        "quality_score": 100,
        "site_name": "Drag13 programmer's blog",
        "canonical_domain": "",
        "favicon_present": 1,
        "schema_org_count": 0,
        "noindex_detected": 0,
        "feed_links_count": 0,
        "https_working": 1,
        "estimated_authority_score": 27,
        "trust_score": 75,
        "nsfw_score": 0,
        "overall_rank_estimate": 3612017,
        "primary_tag": "",
        "tag_codes": "T",
        "manual_verified_status": "",
        "manual_tag_codes": "",
        "manual_rating_delta": 0,
        "manual_authority_delta": 0,
        "manual_trust_delta": 0,
        "manual_note": null,
        "manual_adjusted_by": null,
        "manual_adjusted_at": null,
        "manual_lock_scores": 0,
        "manual_lock_flags": 0,
        "crawl_blocked": 0,
        "crawl_blocked_by": "",
        "crawl_blocked_reason": null,
        "safety_score": 100,
        "fraud_score": 0,
        "legitimacy_score": 53,
        "infrastructure_risk_score": 1,
        "score_confidence": 100,
        "tag_confidence": 72,
        "category_confidence": 22,
        "deep_crawl_pages": 35,
        "resolved_ip": "185.199.108.153",
        "category_candidates_json": "[{\"category\":\"Personal\",\"score\":22},{\"category\":\"Personal\",\"score\":22},{\"category\":\"Developer Tools\",\"score\":17},{\"category\":\"Technology\",\"score\":17}]",
        "page_signals_json": "[{\"path\":\"/posts/rescript-react-vite-guide/index.html\",\"status\":200,\"title\":\"The Complete Guide to Setting up React with ReScript and Vite\",\"word_count\":985,\"summary_text\":\"The Complete Guide to Setting up React with ReScript and Vite The Complete Guide to Setting up React with ReScript and Vite.post .tag{color:var(--hashtag)}HomeThe Complete Guide to Setting up React with ReScript and Vite If you're intrigued by the idea of exploring another strongly typed, functional language, you should definitely give ReScript a try. This guide is designed to assist you in setting up a fundamental React application using ReScript and Vite, offering you a fantastic opportunity to delve into this exciting combination of technologies. With ReScript's type safety and the speed of Vite, you'll be well on your way to building robust and highly performant web applications that are a joy to work with. So, let's embark on this journey of enhancing your web development skills by seamlessly integrating React, ReScript, and Vite into your workf\",\"classification_terms\":[\"posts/rescript-react-vite-guide/index.html\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":2,\"depth\":1},{\"path\":\"/posts/create-new-nextjs-app-with-prettier-eslint-tests/index.html\",\"status\":200,\"title\":\"NextJS with prettier, eslint, husky and test - short guide\",\"word_count\":714,\"summary_text\":\"NextJS with prettier, eslint, husky and test - short guide NextJS with prettier, eslint, husky and test - short guide.post .tag{color:var(--hashtag)}HomeHow to create and configure Next.JS v.13 application with Prettier, Eslint, Husky and Jest This short instruction will guide you through creating a Next.js app, complete with Prettier, ESLint, Husky, and Jest configurations, and deployment on Azure. Learn how to set up a new project, configure Prettier and ESLint, use Husky for pre-commit hooks, write tests with Jest, and deploy your app to Azure for an optimized production environment. Table of Content Create new Next.JS application Setup Prettier Configure Eslint Setup Husky with LintStaged Setup tests with Jest Deployment notes Extra options Before you start Use the console for a better debugging experience, especially for the commit and push p\",\"classification_terms\":[\"posts/create-new-nextjs-app-with-prettier-eslint-tests/index.html\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":1,\"depth\":1},{\"path\":\"/posts/nextjs-new-server-components/index.html\",\"status\":200,\"title\":\"NextJs and New Server Components\",\"word_count\":1159,\"summary_text\":\"NextJs and New Server Components NextJs and New Server Components.post .tag{color:var(--hashtag)}HomeNextJs and new Server Components - How to use and limitations Hello everyone, recently I have spent a lot of time dealing with the new feature in Next.JS - server components, and now I want to share my experience and some thoughts about this update, including the benefits, limitations, and how to use them in real-life scenarios. If you are interested in Next.JS or web performance in general, grab a cup of coffee and let's start reading! Why were server components introduced? Let's start with the most important question - \\\"Why were server components introduced?\\\" As you probably already know, Next.JS works as follows (simplified): The client requests the address served by the Next.JS server. Next.JS, at runtime (optimization\",\"classification_terms\":[\"posts/nextjs-new-server-components/index.html\",\"about\",\"address\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":1,\"depth\":1},{\"path\":\"/react-learning-course-short/react-intro\",\"status\":200,\"title\":\"React For Beginners - What is React\",\"word_count\":613,\"summary_text\":\"React For Beginners - What is React React For Beginners - What is React Free React Course For Beginners L0 - What is React React For Beginners by Itera Key Points The problem What is the React Three pillars of React React - advantages and disadvantages Why to learn React nowadays About me Vitalii Ruban Head of Front-End department in Itera Member of the program committee JsFest Ukraine Love #webperf and #websec The problem How to sync the view and the data Good old time This days When one field depends on another... 🤯 And the async calls comes... And DOM modification is not fast We have only 16.6 ms to render the screen What is the React Simply saying - React is a JavaScript library that: Transforms your data into the markup Redraw the markup when the data changed Do this fast (enough) State ⬇️ React App ⬇️ React ⬇️ Fancy We\",\"classification_terms\":[\"react-learning-course-short/react-intro\",\"about\",\"about me\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":1,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":2,\"depth\":1},{\"path\":\"/react-learning-course-short/react-cra\",\"status\":200,\"title\":\"React For Beginners - A New Project With Create-React-App\",\"word_count\":547,\"summary_text\":\"React For Beginners - A New Project With Create-React-App React For Beginners - A New Project With Create-React-App Free React Course For Beginners L1 - A New Project With Create-React-App React For Beginners by Itera Key Points Starting new React project from scratch using create-react-app Project structure Files you need to know Predefined commands Code examples Alternatives Starting new React project from scratch using create-react-app Open VsCode's console with CTRL+` npx create-react-app myproj --template typescript Let's read it npx create-react-app myproj --template typescript npx - the npm tool that allow you to download npm package and execute it create-react-app - npm package from Meta (Facebook) that creates new project with default structure and all dependencies myproj - name of the project --template typescript - template to use for\",\"classification_terms\":[\"react-learning-course-short/react-cra\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":0,\"depth\":1},{\"path\":\"/react-learning-course-short/react-components\",\"status\":200,\"title\":\"React For Beginners - What is React Component\",\"word_count\":1250,\"summary_text\":\"React For Beginners - What is React Component React For Beginners - What is React Component Free React Course For Beginners L2 - What is React Component React For Beginners by Itera Key Points What is the component Why to use the components Component types How to pass data into the component How to get data from the component Component lifecycle What is the component Component An independent unit of code that encapsulate single, logical functionality From React prospective component is a function or class that accepts props (input) and returns JSX First good candidates are Buttons, inputs, links Cards, grids, decorations Complex stuff you want to hide from yourself How small a component should be It's always much easier to merge components rather than split. Feel free to make them as small as you feel comfortable Why to use the compon\",\"classification_terms\":[\"react-learning-course-short/react-components\",\"returns\",\"links\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":0,\"depth\":1},{\"path\":\"/react-learning-course-short/react-hooks\",\"status\":200,\"title\":\"React For Beginners - React and Hooks\",\"word_count\":611,\"summary_text\":\"React For Beginners - React and Hooks React For Beginners - React and Hooks Free React Course For Beginners L3 - React and Hooks React For Beginners by Itera Key Points What is a hook Hook rules UseState Use Effect UseContext Custom hooks What is a hook Hook as is just a function, that Starts with use Lives only inside functional component or other hooks Hooks extends functional components functionality Hooks allows you to have state, hook into lifecycle, share functionality Appeared since React 16.8 Started from very arguable, now almost the standard Pros Extends functional components functionality Very nice way to share common logic Cons Might become extremely messy Hook rules Name hook with use useState() useCallback() useWhatEverYouWant() Use only inside functional component or other hook Don't use conditionally or in loop\",\"classification_terms\":[\"react-learning-course-short/react-hooks\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":0,\"depth\":1},{\"path\":\"/react-learning-course-short/react-new-component\",\"status\":200,\"title\":\"React For Beginners - Building React Component\",\"word_count\":708,\"summary_text\":\"React For Beginners - Building React Component React For Beginners - Building React Component Free React Course For Beginners L4 - Building React Component React For Beginners by Itera Key Points What is component - quick recap Building \\\"dumb\\\" components - functional and class-based Building \\\"smart\\\" component - functional and class-based What and when to use Components - best practices Program Create class-based, dumb component - MessageBlock Turn it to the functional component Create smart, class-based component - button with a counter inside Rework previous component to the functional What and when to use Best practices What is component - quick recap Component - unit of code that encapsulate single, logical functionality Component can be dumb or smart Component accepts props and returns JSX Component can be build as a class or funct\",\"classification_terms\":[\"react-learning-course-short/react-new-component\",\"returns\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":0,\"depth\":1},{\"path\":\"/react-learning-course-short/react-styling\",\"status\":200,\"title\":\"React For Beginners - React - From CSS to CSSinJS\",\"word_count\":683,\"summary_text\":\"React For Beginners - React - From CSS to CSSinJS React For Beginners - React - From CSS to CSSinJS Free React Course For Beginners L5 - React - From CSS to CSSinJS React For Beginners by Itera Key Points Default way Using CSS modules Preprocessors CSS in JS Default way Just a CSS import \\\"./index.css\\\"; const App = () =&gt; ( &lt;div className=\\\"App\\\"&gt;My app&lt;/div&gt; ) Pros Simple to read - just regular CSS Simple to use - just regular CSS No extra efforts - works out of the box Cons - Conflicts // App.css .root { padding-top: 1em; } // Card.css .root { padding-top: 2em; } // Result .root { padding-top: ??; } Cons - hard to reuse .input:focus { outline: 1px solid brown; } .select:focus { outline: 1px solid brown; } Cons - hard to track not used code .app {font-size: 2rem;} .missing-class {color: red} import \\\"./index.css\\\"; const App = (\",\"classification_terms\":[\"react-learning-course-short/react-styling\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":2,\"depth\":1},{\"path\":\"/react-learning-course-short/react-change-detection\",\"status\":200,\"title\":\"React For Beginners - Tracking Changes\",\"word_count\":398,\"summary_text\":\"React For Beginners - Tracking Changes React For Beginners - Tracking Changes Free React Course For Beginners L5 - Tracking Changes React For Beginners by Itera Key Points What is change detection Implicit change detection with Angular Explicit change detection with React How it works in React (simplified) Typical mistakes What is change detection Change detection - mechanism that tracks data changes and notifies appropriate listeners As an example - look on the BtnWithCounter: state = {counter: 0} ⬇️ Clicked 0 times 🖱️ Click ⬇️ setState({counter:1}) ⬇️ Clicked 1 times It looks very simple from the first sight but imagine: Rich data Rich user interaction Backend interaction 🤯🤯🤯 Two ways to track changes Implicit change detection strategy Angular way class CalculatorService { income: number; setIncome(newIncome){ this.income = n\",\"classification_terms\":[\"react-learning-course-short/react-change-detection\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":0,\"depth\":1},{\"path\":\"/react-learning-course-short/react-state-management\",\"status\":200,\"title\":\"React For Beginners - Managing State in React\",\"word_count\":793,\"summary_text\":\"React For Beginners - Managing State in React React For Beginners - Managing State in React Free React Course For Beginners L6 - Managing State in React React For Beginners by Itera Key Points Problems with setState and useState Context Redux MobX The problem with setState and useState // Component to show user details const L3: FC&lt;UserInputProps&gt; = ({ nationality }) =&gt; ( &lt;strong&gt;{nationality}&lt;/strong&gt; ); // Some component #2 const L2: FC&lt;UserInputProps&gt; = ({ nationality }) =&gt; ( &lt;L3 nationality={nationality} /&gt; ); // Some component #1 const L1: FC&lt;UserInputProps&gt; = ({ nationality }) =&gt; ( &lt;L2 nationality={nationality} /&gt; ); L1 ⬇️ nationality |-> L2 ⬇️ ... ⬇️ nationality |-> LN Imagine, we need to change something A lot of useless work - need to update each component in hierarchy Risk o\",\"classification_terms\":[\"react-learning-course-short/react-state-management\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":0,\"depth\":1},{\"path\":\"/react-learning-course-short/react-forms\",\"status\":200,\"title\":\"React For Beginners - Forms - Default Way and React-Hook-Forms\",\"word_count\":514,\"summary_text\":\"React For Beginners - Forms - Default Way and React-Hook-Forms React For Beginners - Forms - Default Way and React-Hook-Forms Free React Course For Beginners L7 - Forms - Default Way and React-Hook-Forms React For Beginners by Itera Key Points React Forms - default way Building your first form with React Hook Form Validation with Yup React Forms - default way Controlled Forms The kind of a form where values for the fields controlled by the state Create a component with empty form and state class MyForm extends PureComponent { state = { pwd: \\\"\\\" }; render() { return ( My form ); } } Add an input inside the form &lt;input type=\\\"password\\\" name=\\\"pwd\\\" id=\\\"pwd\\\" value={this.state.pwd} onChange={this._handleChange} /&gt; Add handler for the input which will update the state private _handleChange = (e: ChangeEvent&lt;HTMLInputElement&gt;) =&gt; this.setState({\",\"classification_terms\":[\"react-learning-course-short/react-forms\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":1,\"depth\":1},{\"path\":\"/react-learning-course-short/react-router\",\"status\":200,\"title\":\"React For Beginners - Routing in React\",\"word_count\":908,\"summary_text\":\"React For Beginners - Routing in React React For Beginners - Routing in React Free React Course For Beginners L8 - Routing in React React For Beginners by Itera Key Points A cup of theory Install react router Basic setup Data Binding Router guard A cup of theory Default way One route - one physical page served from server Changing the route leads to unload for the current page, and full load for the new page Pros Simplicity Excellent control Cache per page Cons - User Experience User loosing all data (or we need somehow to restore) Reload take some time (even with cache) The solution - use client routing When URL changed - we are staying on the same physical page but the content refreshed by JS This called - Single Page Application approach A single-page application (SPA) is a web application or website that interacts with the\",\"classification_terms\":[\"react-learning-course-short/react-router\",\"store\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":0,\"depth\":1},{\"path\":\"/react-learning-course-short/react-network\",\"status\":200,\"title\":\"React For Beginners - React and Network\",\"word_count\":1009,\"summary_text\":\"React For Beginners - React and Network React For Beginners - React and Network Free React Course For Beginners L9 - React and Network React For Beginners by Itera Key Points Fetch Axios Network and store Typical mistakes Fetch In a nutshell working with network is easy Schema Use fetch api to issue an network request Update state on success Handle error if any Class based component example Define a class with an initial state class FreeApi extends PureComponent { state = { errored: false, apis: [] }; } On ComponentDidMount implement fetching async componentDidMount() { try { const rawData = await fetch(FREE_API_URL); const { entries } = await rawData.json(); this.setState({ errored:false, apis: entries }); } catch (e) { this.setState({ errored: true, apis: [] }); } } Render the result render() { const { apis, errored } = this.s\",\"classification_terms\":[\"react-learning-course-short/react-network\",\"api\",\"store\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":0,\"depth\":1},{\"path\":\"/react-learning-course-short/react-ui-lib\",\"status\":200,\"title\":\"React For Beginners - UI Libraries\",\"word_count\":540,\"summary_text\":\"React For Beginners - UI Libraries React For Beginners - UI Libraries Free React Course For Beginners L10 - UI Libraries React For Beginners by Itera Key Points Purpose Cons How to choose Material UI Purpose Speed up the development Ui libraries provide you with good set of already working components It's much faster to npm i then code, code, code Cover edge cases Good ui libraries already faced tricky cases like accessibility, performance, etc If bug not exists, you will not need to fix it Downsides of using UI lib Discontinuation Any project is a subject to be abandoned Abandoned project means security risks, not fixed bugs, no support for the next versions The solution: find that lib that will abandoned after ending your own project Harder to fix bugs Bugs are everywhere, even in React Fixing bugs in the 3rd party librar\",\"classification_terms\":[\"react-learning-course-short/react-ui-lib\",\"support\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":0,\"depth\":1},{\"path\":\"/react-learning-course-short/react-testing\",\"status\":200,\"title\":\"React For Beginners - Testing Your Code\",\"word_count\":1256,\"summary_text\":\"React For Beginners - Testing Your Code React For Beginners - Testing Your Code Free React Course For Beginners L11 - Testing Your Code React For Beginners by Itera Key Points Why test Testing pyramid What should be tested Testing with Jest Why test Find mistakes earlier People do mistakes, that's normal. Tests help you identify mistakes in earlier stages which makes fix much more easy. Prevent from new mistakes Code is a subject to change. When changing, it's easy to forget update something related or break something else. Tests prevent accidental bugs. Code is cleaner Writing tests, you will eventually use the code. If the code is hard to test - this is a spot that code will be hard to use. Tests highlight bad code smells. Code is better Writing tests, you are thinking about edge cases - errors, fails and other crap happening\",\"classification_terms\":[\"react-learning-course-short/react-testing\",\"about\",\"help\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":0,\"depth\":1},{\"path\":\"/react-learning-course-short/typescript-intro\",\"status\":200,\"title\":\"React For Beginners - TypeScript For Beginners\",\"word_count\":757,\"summary_text\":\"React For Beginners - TypeScript For Beginners React For Beginners - TypeScript For Beginners Free React Course For Beginners L12 - TypeScript For Beginners React For Beginners by Itera Key Points Primitives Functions CustomTypes Generics TypeAssertions TypeScript is JavaScript with syntax for types. TypeScript is a strongly typed programming language that builds on JavaScript scale (C) The good part of TypeScript - it's progressive With tsconfig.json you can have TypeScript whatever strict you want TypeScript also able to run JavaScript which enables taking benefits from both The bad parts of TypeScript Errors in TypeScript are absolutely awful, especially with complex types Dealing with TypeScript npm i typescript -D npm i ts-node -D npx tsc --init npx ts-node src/index.ts Tune tsconfig.json for your needs Documentation is here Primi\",\"classification_terms\":[\"react-learning-course-short/typescript-intro\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":0,\"depth\":1},{\"path\":\"/posts/typescript-tips-tricks-case-study/index.html\",\"status\":200,\"title\":\"Advanced TypeScript - Tips and Tricks\",\"word_count\":1571,\"summary_text\":\"Advanced TypeScript - Tips and Tricks Advanced TypeScript - Tips and Tricks.post .tag{color:var(--hashtag)}HomeAdvanced TypeScript - Tips and Tricks It would seem that in 2022 it is a bit too late to talk about TypeScript - the technology is well known and popular. Despite this, some times TypeScript still used half-heartedly. Simple type annotations, null checking and nothing more. Therefore, I brought some interesting, purely practical cases to show mighty TypeScript in action! Narrowing primitives Let's start simple. Imagine that we have a function that takes a key as input, extracts a translation from the dictionary by the key and returns it. What will be the type of this key? Most likely - string. But it is clear that not everyone string is a valid key - we certainly do not need the entire British Encyclopedia right? And\",\"classification_terms\":[\"posts/typescript-tips-tricks-case-study/index.html\",\"about\",\"returns\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":1,\"depth\":1},{\"path\":\"/posts/react-performance-puppeteer-limits/index.html\",\"status\":200,\"title\":\"Performance testing with slow network and CPU using Puppeteer and React\",\"word_count\":971,\"summary_text\":\"Performance testing with slow network and CPU using Puppeteer and React Performance testing with slow network and CPU using Puppeteer and React.post .tag{color:var(--hashtag)}HomePerformance testing on a slow network and weak CPU using Puppeteer and React In the previous article I've shown how to extract performance metrics from the React-based application using Puppeteer. We got ScriptDuration, Contentful Paint, Time To First Byte, Largest Contentful Paint, and other metrics. I also showed how to extract custom performance events using the performance API. Today we will take a look into various testing conditions you might consider applying. We will set up the network limitations to simulate a slow 3g network, and we also will limit the CPU power to get a better understanding of how our application behaves on weak devices. Also, I will show how to test cache\",\"classification_terms\":[\"posts/react-performance-puppeteer-limits/index.html\",\"api\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":2,\"depth\":1},{\"path\":\"/posts/react-performance-puppeteer-profile/index.html\",\"status\":200,\"title\":\"Getting performance metrics using Puppeteer and React\",\"word_count\":2564,\"summary_text\":\"Getting performance metrics using Puppeteer and React Getting performance metrics using Puppeteer and React.post .tag{color:var(--hashtag)}HomeHow to get performance metrics and web vitals using Puppeteer, React and TypeScript, Part 1 In this article, I will demonstrate how to build the script to automate gathering performance metrics like First Contentful Paint and Core Web Vitals from the React-based application using Puppeteer and TypeScript. I will also describe how to create and extract your own performance events using the React Profiler component. This might be useful if you decide to do some performance research or implement advanced performance testing into your CI/CD pipeline. The Plan Because of the large amount of material and code, I will split the content into two parts. The first one (this one) will be about gathering performan\",\"classification_terms\":[\"posts/react-performance-puppeteer-profile/index.html\",\"about\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":4,\"depth\":1},{\"path\":\"/posts/how-turn-off-floc-javascript/index.html\",\"status\":200,\"title\":\"Turning FLoC off using JavaScript\",\"word_count\":849,\"summary_text\":\"Turning FLoC off using JavaScript Turning FLoC off using JavaScript.post .tag{color:var(--hashtag)}HomeHow to opt-out Federated Learning of Cohorts (FLoC) using JavaScript Federated Learning of Cohorts and default way to opt-out Federated Learning of Cohorts (FLoC) - is the new way proposed by Google that allows Chrome to collect and share customers' personal information without the need for cookies. It uses the browser's history (which had never opened) and some other methods to group people into cohorts based on their interests and show them some ads which raise some questions about privacy. Introducing this technology, Google states that FLoC will keep your privacy, however some concerns still exists. To give an option to fix this, Google provides the way to opt-out of the FLoC by using HTTP Header Permissions-Policy wi\",\"classification_terms\":[\"posts/how-turn-off-floc-javascript/index.html\",\"about\",\"privacy\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":1,\"depth\":1},{\"path\":\"/posts/typescript-tricks-utility-examples/index.html\",\"status\":200,\"title\":\"TypeScript Tips and Tricks - Utility Types With Examples\",\"word_count\":752,\"summary_text\":\"TypeScript Tips and Tricks - Utility Types With Examples TypeScript Tips and Tricks - Utility Types With Examples.post .tag{color:var(--hashtag)}HomeTypeScript Tips and Tricks - Utility Types With Examples TypeScript is a very powerful language, however, it heavily relies on the types. And sometimes, you may found that you write more types than actual code. In this case, you should take a look into the Utility types that will help you to write fewer types and still keep your code type-safe. Let's start from the simple example - imagine that you have a list of events produced by the application and a list of handlers for them. So you may write (don't do this way) something like this: type Action = \\\"move\\\" | \\\"stop\\\"; function handleAction(action: Action) { if (action === \\\"move\\\") { console.log(\\\"i am moving\\\"); } if (action === \\\"stop\\\") { console.log(\\\"i\",\"classification_terms\":[\"posts/typescript-tricks-utility-examples/index.html\",\"help\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":1,\"depth\":1},{\"path\":\"/posts/typescript-tips-tricks-declarations/index.html\",\"status\":200,\"title\":\"TypeScript Tips and Tricks - Declarations With Examples\",\"word_count\":711,\"summary_text\":\"TypeScript Tips and Tricks - Declarations With Examples TypeScript Tips and Tricks - Declarations With Examples.post .tag{color:var(--hashtag)}HomeTypeScript Tips and Tricks - Declarations With Examples TypeScript is a very powerful language and it is becoming more and more popular. I would say that TypeScript is that kind of language that is easy to learn but difficult to master. In this article, I will show you some useful tips and tricks about TypeScript's declarations that may help you in everyday coding and will keep your code type-safe. Global object augmentation in TypeScript The declaration is one of the most important parts of the TypeScript and of course, you already familiar with it. Despite this, sometimes declarations might be tricky. Imagine that you need to extend global object (like Window) with custom properties. If you will tr\",\"classification_terms\":[\"posts/typescript-tips-tricks-declarations/index.html\",\"about\",\"help\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":1,\"depth\":1},{\"path\":\"/posts/perfrunner-intro/index.html\",\"status\":200,\"title\":\"Perfrunner - automation tool to track website performance\",\"word_count\":773,\"summary_text\":\"Perfrunner - automation tool to track website performance Perfrunner - automation tool to track website performance.post .tag{color:var(--hashtag)}HomePerfrunner - automated tool to track your website speed changes Quick intro A few months ago I worked on performance improvements for one React-based web application. I tried different tricks to improve initial application loading and I was really annoyed with the way of testing my changes. I had to launch the application several times to get average results. I had to repeat all launches against at least two types of networks (4g and my current). And I had to repeat abovementioned tests once again for cache and cache-less scenarios. For the one single change, I had to run at least 12 tests. Needless to say, this was not fun. I decided that I don't want to do this anymore and this is how the Perfrun\",\"classification_terms\":[\"posts/perfrunner-intro/index.html\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":1,\"depth\":1},{\"path\":\"/posts/react-inline-runtimer-chunk/index.html\",\"status\":200,\"title\":\"How to use React without unsafe-inline runtime chunk and why\",\"word_count\":887,\"summary_text\":\"How to use React without unsafe-inline runtime chunk and why How to use React without unsafe-inline runtime chunk and why.post .tag{color:var(--hashtag)}HomeHow to use React without unsafe-inline and why React.JS is an awesome library that widely used all over the world. However, it also contains some pitfalls that might negatively impact your application. And here I want to discuss one of such pitfalls - inlined runtime chunk that might prevent you from correct using one of the most useful security header - Content-Security-Policy. Identifing the issue Let's start. If you have ever opened the output index.html, you've probably already seen something like this: ... &lt;!--index.html--&gt; &lt;div id=\\\"root\\\"&gt;&lt;/div&gt; &lt;script&gt;!function (e) { function r(r) { for (var n, l, f = r[0], i = r[1], a = r[2], c = 0, s = []; c &lt; f.length; c++)l\",\"classification_terms\":[\"posts/react-inline-runtimer-chunk/index.html\",\"help\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":3,\"depth\":1},{\"path\":\"/posts/custom-typings/index.html\",\"status\":200,\"title\":\"How to add custom types into the TypeScript project\",\"word_count\":559,\"summary_text\":\"How to add custom types into the TypeScript project How to add custom types into the TypeScript project.post .tag{color:var(--hashtag)}HomeHow to add custom types to the TypeScript project Working with TypeScript is very comfortable. It provides Intellisense, type-checking, and makes the developer's life much easier. But, sometimes, when I am using external libraries, I got a problem. They don't provide types or shipped types that are outdated. In this case, there is no other option but to define custom typings my own. Luckily, it's not that hard as you may expect. Before we start Before you start adding custom types you need to ensure that there are no original types. Nowadays, packages that don't ship typings with themselves could be found under @types/package-name. So, first of all - check @types. And only if there is nothing suitable, c\",\"classification_terms\":[\"posts/custom-typings/index.html\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":1,\"depth\":1},{\"path\":\"/page1.html\",\"status\":200,\"title\":\"Drag13 Dev Blog - JavaScript, Performance, Security\",\"word_count\":319,\"summary_text\":\"Drag13 Dev Blog - JavaScript, Performance, Security Drag13 Dev Blog - JavaScript, Performance, SecurityHomeBlog about JavaScript, performance and securityTop-5 HTTP Security Headers in 2020#security #http-headers #content-security-policy Nowadays, security is important as never before. I've prepared a very short article about the Top-5 security headers in 2020 that will help your site keep your users in safety.ContinueReact.JS application, performance and -500 milliseconds at launch - the history of our optimizations in numbers#react #performance Simple performance optimizations and -500 milliseconds at launch for the create-react-app.Continue in RussianProfile loading of Habr or how 189 requests influence the rendering#performance If you are interested in how to profile and (what is more important) understand the profiling results - here i\",\"classification_terms\":[\"page1.html\",\"about\",\"help\",\"blog\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":0,\"depth\":1},{\"path\":\"/posts/rescript-react-vite-guide-ua/index.html\",\"status\":200,\"title\":\"React, Rescript, Vite - як ствоити проект\",\"word_count\":839,\"summary_text\":\"React, Rescript, Vite - як ствоити проект React, Rescript, Vite - як ствоити проект.post .tag{color:var(--hashtag)}HomeКоротка інструкція як створити новий React застосунок за допомогою ReScript та Vite Попередження: ця стаття не про переваги та недоліки ReScript, це просто інструкція як підняти React проект з ReScript за допомогою Vite. Якщо ви не хочете читати - просто склонуйте цей репозиторій, встановіть залежності та експерементуйте. Передумови Перш ніж приступити до налаштування, переконайтеся, що на вашій системі встановлені Node.js та npm. Вам також знадобиться редактор коду, і для цього прикладу я буду використовувати Visual Studio Code. Крок 1: Ініціалізація проекту Vite Для початку відкрийте ваш термінал та виконайте наступну команду: npm init vite retest Ця команда ініціалізує проект Vite з назвою \\\"retest\\\", який надає\",\"classification_terms\":[\"posts/rescript-react-vite-guide-ua/index.html\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":2,\"depth\":2},{\"path\":\"/posts/create-new-nextjs-app-with-prettier-eslint-tests-ua/index.html\",\"status\":200,\"title\":\"NextJS з prettier, eslint, husky та тестуванням - короткий посібник\",\"word_count\":712,\"summary_text\":\"NextJS з prettier, eslint, husky та тестуванням - короткий посібник NextJS з prettier, eslint, husky та тестуванням - короткий посібник.post .tag{color:var(--hashtag)}HomeЯк створити та налаштувати додаток Next.JS v.13 з Prettier, Eslint, Husky та Jest Ця коротка інструкція допоможе вам створити додаток Next.js з конфігураціями Prettier, ESLint, Husky та Jest, а також розгорнути його на Azure. Дізнайтеся, як налаштувати новий проект, налаштувати Prettier та ESLint, використовувати Husky для перевірки перед комітом, писати тести з Jest та розгортати ваш додаток на Azure для оптимізованого середовища виробництва. Зміст Створюємо новий додаток Next.JS Налаштовуємо Prettier Налаштовуємо Eslint Налаштовуємо Husky з lint-staged Налаштовуємо тести з Jest Примітки щодо розгортання Додаткові опції Перед початком Використовуйте консоль для кращого досвіду налагоджен\",\"classification_terms\":[\"posts/create-new-nextjs-app-with-prettier-eslint-tests-ua/index.html\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":1,\"depth\":2},{\"path\":\"/posts/react-performance-puppeteer-profile\",\"status\":200,\"title\":\"Getting performance metrics using Puppeteer and React\",\"word_count\":2564,\"summary_text\":\"Getting performance metrics using Puppeteer and React Getting performance metrics using Puppeteer and React.post .tag{color:var(--hashtag)}HomeHow to get performance metrics and web vitals using Puppeteer, React and TypeScript, Part 1 In this article, I will demonstrate how to build the script to automate gathering performance metrics like First Contentful Paint and Core Web Vitals from the React-based application using Puppeteer and TypeScript. I will also describe how to create and extract your own performance events using the React Profiler component. This might be useful if you decide to do some performance research or implement advanced performance testing into your CI/CD pipeline. The Plan Because of the large amount of material and code, I will split the content into two parts. The first one (this one) will be about gathering performan\",\"classification_terms\":[\"posts/react-performance-puppeteer-profile\",\"about\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":4,\"depth\":2},{\"path\":\"/posts/security-headers/index.html\",\"status\":200,\"title\":\"Top 5 HTTP Security Headers\",\"word_count\":1132,\"summary_text\":\"Top 5 HTTP Security Headers Top 5 HTTP Security Headers.post .tag{color:var(--hashtag)}HomeTop-5 HTTP Security Headers Nowadays, security is important as never before. I've prepared a very small article about the Top-5 security headers in 2020 that will help your site keep your users in safety. Have a nice reading! Content-Security-Policy One of the most important security header. It was created to prevent the usage of any resource from an untrusted source. Let's go to the short example first: Evil Bob found XSS vulnerability on Alice's site. He decides to inject the script into the web-page to steal some customer data. He put this script tag into her page &lt;script src=\\\"https://my-evilt-site.org/very-evil-script.js\\\"&gt;&lt;/script&gt; and waits for the results Luckily, Alice knows about CSP header and already added\",\"classification_terms\":[\"posts/security-headers/index.html\",\"about\",\"help\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":0,\"depth\":2},{\"path\":\"/posts/v8-bytecode/index.html\",\"status\":200,\"title\":\"How to get javascript bytecode from V8 and others in 2019\",\"word_count\":625,\"summary_text\":\"How to get javascript bytecode from V8 and others in 2019 How to get javascript bytecode from V8 and others in 2019.post .tag{color:var(--hashtag)}HomeHow to get javascript bytecode from V8 and others in 2019 Have you ever thought about how your javascript code looks like in bytecode? If yes, just follow the white rabbit. Install latest Node.Js or check your current version using -v command. If it's 8.3 or above, everything is ok. If no, check the second part of this article. Then run your code with a flag --print-bytecode. It will instruct the Node to display the bytecode directly to your console. node --print-bytecode --eval 1+1 After executing this command you will see a very long list with a code like this: Parameter count 2 Register count 3 Frame size 24 12 E&gt; 000002252055F082 @ 0 : a5 StackCheck 33 S&gt; 000002252055F083 @ 1 : 0b LdaZero\",\"classification_terms\":[\"posts/v8-bytecode/index.html\",\"about\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":3,\"depth\":2},{\"path\":\"/posts/start-new-project/index.html\",\"status\":200,\"title\":\"How to start a new JavaScript project with automated formatting, linting, testing, and documentation\",\"word_count\":1336,\"summary_text\":\"How to start a new JavaScript project with automated formatting, linting, testing, and documentation How to start a new JavaScript project with automated formatting, linting, testing, and documentation.post .tag{color:var(--hashtag)}HomeHow to start a new JavaScript project with automated formatting, linting, testing, and documentation Keeping your code consistent and well-formatted not an easy task even when you work alone. But when you work with a team or with open source projects all start getting even harder. Everyone has their own code style, someone doesn't run tests, and no one writes documentation. This article will help you to set up all these things and even more - automate this routine to never do it manually. After reading you will get your own npm-ready project with the next features: Text formatting and code style Automated tests with code coverage and threshold Unified comm\",\"classification_terms\":[\"posts/start-new-project/index.html\",\"help\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":0,\"depth\":2},{\"path\":\"/posts/ci-cd-net/index.html\",\"status\":200,\"title\":\"Easy Continuous Integration for your GitHub project\",\"word_count\":974,\"summary_text\":\"Easy Continuous Integration for your GitHub project Easy Continuous Integration for your GitHub project.post .tag{color:var(--hashtag)}HomeFree and easy Continuous Integration for your GitHub project with three easy steps - build, test, deploy Hi guys! Today we will learn how to setup Continuous Integration process for the C# project hosted on GitHub. This is very easy, can really improve your code quality and you always be sure that no one destroys your code with latest commit. Are you interested? Let's give it a try! You will need GitHub account .NET Core SDK &gt; 2.1. Visual Studio 2017 Azure account - optional Let's start. Start a new project Create a new repository on GitHub and clone it locally. Don't forget to select .gitignore file template for VisualStudio to keep your repository clean and nice. Than generate new .NET Сore web appl\",\"classification_terms\":[\"posts/ci-cd-net/index.html\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":0,\"depth\":2},{\"path\":\"/index.html\",\"status\":200,\"title\":\"Drag13 Dev Blog - JavaScript, Performance, Security\",\"word_count\":1348,\"summary_text\":\"Drag13 Dev Blog - JavaScript, Performance, Security Drag13 Dev Blog - JavaScript, Performance, Security.pp{margin-top:3rem;content-visibility:auto;contain-intrinsic-size:600px}.pp .header{margin:0 0 1rem;border-bottom:0;padding:0}.pp .text{color:inherit}.pp .tags{color:var(--hashtag);margin-bottom:1rem}.pp .kdpv-link{display:block;margin-bottom:1rem}.pp .img{height:auto}.pp .continue{display:block;border-bottom:1px solid var(--light-gray)}HomeBlog about JavaScript, performance and securityThe Complete Guide to Setting up React with ReScript and Vite#rescript #react #vite #new-project #how-to If you're intrigued by the idea of exploring another strongly typed, functional language, you should definitely give ReScript a try. This guide is designed to assist you in setting up a fundamental React application using ReScript and Vite, offering you\",\"classification_terms\":[\"index.html\",\"about\",\"blog\"],\"external_refs\":[],\"password_input_count\":0,\"email_input_count\":0,\"tel_input_count\":0,\"otp_term_count\":0,\"login_form_count\":0,\"checkout_form_count\":0,\"wallet_prompt_count\":0,\"offdomain_form_actions\":0,\"suspicious_script_refs_count\":0,\"external_script_hosts\":[],\"executable_download_count\":0,\"archive_download_count\":0,\"apk_download_count\":0,\"phone_number_count\":0,\"depth\":2}]",
        "score_reasons_json": "[\"Category confidence was reduced, so the classifier fell back to the broader parent category.\",\"Category evidence stayed thin, so the output was softened to a broader classification.\",\"Clean low-risk signals now remain neutral instead of receiving a caution tag from low confidence alone.\"]",
        "estimated_monthly_visitors": 432,
        "route_domain": "drag13.io",
        "display_domain": "drag13.io"
    },
    "explainability": {
        "summary": "drag13.io currently scores 48/100. Technical and crawl-quality evidence are doing most of the lifting for the score. Evidence confidence is strong enough for a relatively stable read. This is an estimated profile rather than a manually tracked one. Crawler access looks clean.",
        "badges": [
            {
                "label": "Profile",
                "value": "Estimated profile",
                "tone": "unknown",
                "detail": null
            },
            {
                "label": "Evidence confidence",
                "value": "High confidence",
                "tone": "good",
                "detail": "100/100"
            },
            {
                "label": "Traffic confidence",
                "value": "Moderate confidence",
                "tone": "caution",
                "detail": "48/100"
            },
            {
                "label": "Crawler access",
                "value": "Clean visibility",
                "tone": "good",
                "detail": null
            }
        ],
        "weighted_contributions": [
            {
                "label": "Quality system",
                "points": "+34.0",
                "tone": "good",
                "detail": "Technical quality, crawl depth, page structure, and implementation hygiene. Current subsystem score: 100/100."
            },
            {
                "label": "Reputation system",
                "points": "+12.9",
                "tone": "risk",
                "detail": "Authority, search visibility, reach, engagement, and registry stability. Current subsystem score: 38/100."
            },
            {
                "label": "Safety system",
                "points": "+32.0",
                "tone": "good",
                "detail": "Fraud, spam, and trust signals from infrastructure, crawl, and registry evidence. Current subsystem score: 100/100."
            },
            {
                "label": "Risk clamp",
                "points": "-31.0",
                "tone": "risk",
                "detail": "Safety thresholds capped the final score until the risk profile improves."
            }
        ],
        "evidence_cards": [
            {
                "label": "Authority and trust",
                "value": "29/100 · trust 67/100",
                "tone": "caution",
                "detail": "235 monthly visitors, 33 organic keywords, brand completeness 83/100, engagement 90/100."
            },
            {
                "label": "Backlink and search evidence",
                "value": "1 referring domains",
                "tone": "good",
                "detail": "1 backlinks across 1 referring domains. Diversity 92/100; spam penalty 0."
            },
            {
                "label": "Registry and domain stability",
                "value": "0.0 years old",
                "tone": "good",
                "detail": "Stability 100/100 · age 0.0 years."
            },
            {
                "label": "Safety and fraud posture",
                "value": "Safety 100/100 · fraud 0/100",
                "tone": "good",
                "detail": "Safety 100/100 · fraud 0/100."
            }
        ],
        "positives": [
            "Low registrar / ownership churn with solid registry stability.",
            "Healthy crawl quality and on-page completeness.",
            "Registry history looks stable, which supports legitimacy and trust.",
            "HTTPS is working, so the site clears a basic transport-security check.",
            "Backlink diversity looks broad enough to strengthen authority confidence."
        ],
        "risks": [],
        "freshness": [
            {
                "label": "Crawl evidence",
                "value": "2026-04-03 22:12:27",
                "tone": "risk",
                "detail": "Crawl and page content sample. Age: 2mo ago."
            },
            {
                "label": "WHOIS snapshot",
                "value": "2026-04-03 22:12:26",
                "tone": "risk",
                "detail": "Registry profile and stability signals. Age: 2mo ago."
            },
            {
                "label": "Keyword view",
                "value": "2026-06-25 07:02:34",
                "tone": "good",
                "detail": "Estimated visibility until tracked keyword snapshots exist. Age: 0s ago."
            },
            {
                "label": "Rank history",
                "value": "2026-06-25 07:02:34",
                "tone": "good",
                "detail": "Estimated trend derived from current profile and crawl signals. Age: 0s ago."
            },
            {
                "label": "Audience geography",
                "value": "Not captured yet",
                "tone": "unknown",
                "detail": "Audience mix is estimated from available signals rather than first-party audience logs."
            }
        ],
        "section_notes": {
            "audience": "Audience geography is estimated from category, country, traffic mix, and brand signals until first-party audience data is collected.",
            "keywords": "Top keywords are estimated from crawl language, brand, category, and visibility signals until tracked keyword snapshots are stored.",
            "history": "Rank history is estimated from the current profile because no stored history exists for this domain yet."
        },
        "base_weighted_score": 79,
        "fraud_clamp_penalty": 31,
        "final_score": 48
    },
    "insight_snapshot": {
        "version": 1,
        "generated_at": "2026-06-25T07:02:34+00:00",
        "domain": "drag13.io",
        "display_name": "Drag13 programmer's blog",
        "is_tracked": false,
        "is_estimated": true,
        "overall_score": 48,
        "authority_score": 29,
        "trust_score": 67,
        "safety_score": 100,
        "fraud_score": 0,
        "confidence_score": 100,
        "traffic_confidence": 48,
        "last_crawled_at": "2026-04-03 22:12:27",
        "crawl_blocked": false,
        "summary": "drag13.io currently scores 48/100. Technical and crawl-quality evidence are doing most of the lifting for the score. Evidence confidence is strong enough for a relatively stable read. This is an estimated profile rather than a manually tracked one. Crawler access looks clean.",
        "badges": [
            {
                "label": "Profile",
                "value": "Estimated profile",
                "tone": "unknown",
                "detail": null
            },
            {
                "label": "Evidence confidence",
                "value": "High confidence",
                "tone": "good",
                "detail": "100/100"
            },
            {
                "label": "Traffic confidence",
                "value": "Moderate confidence",
                "tone": "caution",
                "detail": "48/100"
            },
            {
                "label": "Crawler access",
                "value": "Clean visibility",
                "tone": "good",
                "detail": null
            }
        ],
        "top_positive_signals": [
            "Low registrar / ownership churn with solid registry stability.",
            "Healthy crawl quality and on-page completeness.",
            "Registry history looks stable, which supports legitimacy and trust.",
            "HTTPS is working, so the site clears a basic transport-security check.",
            "Backlink diversity looks broad enough to strengthen authority confidence."
        ],
        "top_risk_signals": [],
        "freshness": [
            {
                "label": "Crawl evidence",
                "value": "2026-04-03 22:12:27",
                "tone": "risk",
                "detail": "Crawl and page content sample. Age: 2mo ago."
            },
            {
                "label": "WHOIS snapshot",
                "value": "2026-04-03 22:12:26",
                "tone": "risk",
                "detail": "Registry profile and stability signals. Age: 2mo ago."
            },
            {
                "label": "Keyword view",
                "value": "2026-06-25 07:02:34",
                "tone": "good",
                "detail": "Estimated visibility until tracked keyword snapshots exist. Age: 0s ago."
            },
            {
                "label": "Rank history",
                "value": "2026-06-25 07:02:34",
                "tone": "good",
                "detail": "Estimated trend derived from current profile and crawl signals. Age: 0s ago."
            },
            {
                "label": "Audience geography",
                "value": "Not captured yet",
                "tone": "unknown",
                "detail": "Audience mix is estimated from available signals rather than first-party audience logs."
            }
        ],
        "top_tags": []
    },
    "is_tracked": false,
    "is_estimated": true,
    "live_state": {
        "status": "processed",
        "status_label": "Snapshot available",
        "message": "The latest crawl snapshot is ready. Background enrichment queues are clear.",
        "updated_at": "2026-03-19 17:35:48"
    },
    "refresh_state": {
        "canRequest": true,
        "queued": false,
        "processing": false,
        "stageKey": "idle",
        "stageLabel": "Ready",
        "cooldownUntil": null,
        "message": "The latest crawl has finished and all refresh queues are clear.",
        "action": "/domain/drag13.io/refresh",
        "isGuestCooldown": false,
        "cooldownSeconds": 0
    },
    "urlscan_report": {
        "domain": "drag13.io",
        "status": "idle",
        "submitted_at": null,
        "completed_at": null,
        "last_checked_at": null,
        "last_error": "",
        "submitted_url": "https://drag13.io/",
        "uuid": "",
        "result_url": "",
        "api_result_url": "",
        "visibility": "public",
        "summary": "No urlscan.io report has been requested for this domain yet.",
        "report": [],
        "report_summary": [],
        "is_fresh": false,
        "can_retry": true,
        "poll_after_seconds": 20
    }
}