{"id":445,"date":"2026-05-06T07:32:51","date_gmt":"2026-05-06T07:32:51","guid":{"rendered":"https:\/\/gonomadlife.com\/?page_id=445"},"modified":"2026-05-06T07:32:51","modified_gmt":"2026-05-06T07:32:51","slug":"best-cities-for-digital-nomads-2025-go-nomad-life","status":"publish","type":"page","link":"https:\/\/gonomadlife.com\/index.php\/best-cities-for-digital-nomads-2025-go-nomad-life\/","title":{"rendered":"Best Cities for Digital Nomads 2025 \u2014 Go Nomad Life"},"content":{"rendered":"<p><!DOCTYPE html><br \/>\n<html lang=\"en\"><br \/>\n<head><br \/>\n<meta charset=\"UTF-8\"><br \/>\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><br \/>\n<title>Best Cities for Digital Nomads 2025 \u2014 Go Nomad Life<\/title>\n<link rel=\"preconnect\" href=\"https:\/\/fonts.googleapis.com\">\n<link rel=\"preconnect\" href=\"https:\/\/fonts.gstatic.com\" crossorigin>\n<link href=\"https:\/\/fonts.googleapis.com\/css2?family=Syne:wght@400;500;600;700;800&#038;family=DM+Sans:ital,opsz,wght@0,9..40,300;0,9..40,400;0,9..40,500;1,9..40,300&#038;display=swap\" rel=\"stylesheet\">\n<style>\n  *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }<\/p>\n<p>  :root {\n    --bg: #0d0d0d;\n    --bg2: #161616;\n    --bg3: #1e1e1e;\n    --border: rgba(255,255,255,0.08);\n    --border2: rgba(255,255,255,0.14);\n    --text: #f0ede8;\n    --text2: #9a9690;\n    --text3: #5a5752;\n    --accent: #d4f73e;\n    --accent2: #a8c530;\n    --accent-text: #1a2200;\n    --teal: #3ee8c8;\n    --coral: #ff6b4a;\n    --amber: #f5a623;\n    --radius: 14px;\n    --radius-sm: 8px;\n    --font-display: 'Syne', sans-serif;\n    --font-body: 'DM Sans', sans-serif;\n  }<\/p>\n<p>  html { scroll-behavior: smooth; }<\/p>\n<p>  body {\n    background: var(--bg);\n    color: var(--text);\n    font-family: var(--font-body);\n    font-size: 15px;\n    line-height: 1.6;\n    min-height: 100vh;\n  }<\/p>\n<p>  .site-header {\n    border-bottom: 1px solid var(--border);\n    padding: 18px 40px;\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n    position: sticky;\n    top: 0;\n    background: rgba(13,13,13,0.92);\n    backdrop-filter: blur(12px);\n    z-index: 100;\n  }\n  .logo {\n    font-family: var(--font-display);\n    font-weight: 700;\n    font-size: 17px;\n    color: var(--text);\n    text-decoration: none;\n    letter-spacing: -0.02em;\n  }\n  .logo span { color: var(--accent); }\n  .header-tag {\n    font-size: 12px;\n    color: var(--text3);\n    letter-spacing: 0.08em;\n    text-transform: uppercase;\n  }<\/p>\n<p>  .hero {\n    padding: 80px 40px 60px;\n    max-width: 1200px;\n    margin: 0 auto;\n    position: relative;\n  }\n  .hero-label {\n    display: inline-flex;\n    align-items: center;\n    gap: 8px;\n    background: rgba(212,247,62,0.1);\n    border: 1px solid rgba(212,247,62,0.25);\n    color: var(--accent);\n    font-size: 11px;\n    font-weight: 500;\n    letter-spacing: 0.1em;\n    text-transform: uppercase;\n    padding: 5px 14px;\n    border-radius: 30px;\n    margin-bottom: 28px;\n  }\n  .hero-label::before { content: \"\u25cf\"; font-size: 8px; }\n  .hero h1 {\n    font-family: var(--font-display);\n    font-size: clamp(36px, 5vw, 64px);\n    font-weight: 800;\n    line-height: 1.05;\n    letter-spacing: -0.03em;\n    color: var(--text);\n    margin-bottom: 20px;\n    max-width: 700px;\n  }\n  .hero h1 em { font-style: normal; color: var(--accent); }\n  .hero-sub {\n    font-size: 16px;\n    color: var(--text2);\n    max-width: 520px;\n    margin-bottom: 40px;\n    font-weight: 300;\n    line-height: 1.7;\n  }\n  .hero-stats { display: flex; gap: 40px; flex-wrap: wrap; }\n  .hero-stat { display: flex; flex-direction: column; gap: 2px; }\n  .hero-stat strong {\n    font-family: var(--font-display);\n    font-size: 28px;\n    font-weight: 700;\n    color: var(--text);\n    letter-spacing: -0.02em;\n  }\n  .hero-stat span { font-size: 12px; color: var(--text3); text-transform: uppercase; letter-spacing: 0.06em; }<\/p>\n<p>  .filters-section {\n    background: var(--bg2);\n    border-top: 1px solid var(--border);\n    border-bottom: 1px solid var(--border);\n    padding: 28px 40px;\n    position: sticky;\n    top: 57px;\n    z-index: 90;\n  }\n  .filters-inner { max-width: 1200px; margin: 0 auto; }\n  .filters-row {\n    display: flex;\n    flex-wrap: wrap;\n    gap: 12px;\n    align-items: flex-end;\n    margin-bottom: 16px;\n  }\n  .filter-group {\n    display: flex;\n    flex-direction: column;\n    gap: 6px;\n    flex: 1;\n    min-width: 130px;\n    max-width: 200px;\n  }\n  .filter-group label {\n    font-size: 10px;\n    text-transform: uppercase;\n    letter-spacing: 0.1em;\n    color: var(--text3);\n    font-weight: 500;\n  }\n  .filter-group select {\n    background: var(--bg3);\n    border: 1px solid var(--border2);\n    color: var(--text);\n    font-family: var(--font-body);\n    font-size: 13px;\n    padding: 9px 14px;\n    border-radius: var(--radius-sm);\n    cursor: pointer;\n    appearance: none;\n    background-image: url(\"data:image\/svg+xml,%3Csvg xmlns='http:\/\/www.w3.org\/2000\/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%235a5752' d='M6 8L1 3h10z'\/%3E%3C\/svg%3E\");\n    background-repeat: no-repeat;\n    background-position: right 12px center;\n    padding-right: 32px;\n    transition: border-color 0.2s;\n  }\n  .filter-group select:hover { border-color: var(--border2); }\n  .filter-group select:focus { outline: none; border-color: var(--accent); }\n  .filter-group select option { background: #1e1e1e; }<\/p>\n<p>  .sort-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }\n  .sort-label { font-size: 11px; color: var(--text3); text-transform: uppercase; letter-spacing: 0.08em; margin-right: 4px; }\n  .sort-btn {\n    font-family: var(--font-body);\n    font-size: 12px;\n    padding: 6px 14px;\n    border-radius: 30px;\n    border: 1px solid var(--border2);\n    background: transparent;\n    color: var(--text2);\n    cursor: pointer;\n    transition: all 0.15s;\n    letter-spacing: 0.02em;\n  }\n  .sort-btn:hover { border-color: rgba(255,255,255,0.25); color: var(--text); }\n  .sort-btn.active { background: var(--accent); color: var(--accent-text); border-color: var(--accent); font-weight: 600; }<\/p>\n<p>  .results-section { max-width: 1200px; margin: 0 auto; padding: 40px 40px 80px; }\n  .results-meta {\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n    margin-bottom: 28px;\n    flex-wrap: wrap;\n    gap: 12px;\n  }\n  .results-count { font-size: 13px; color: var(--text3); }\n  .results-count strong { color: var(--text2); }<\/p>\n<p>  .grid {\n    display: grid;\n    grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));\n    gap: 20px;\n  }<\/p>\n<p>  .card {\n    background: var(--bg2);\n    border: 1px solid var(--border);\n    border-radius: var(--radius);\n    overflow: hidden;\n    transition: border-color 0.2s, transform 0.2s;\n    animation: fadeUp 0.35s ease both;\n  }\n  @keyframes fadeUp {\n    from { opacity: 0; transform: translateY(16px); }\n    to { opacity: 1; transform: translateY(0); }\n  }\n  .card:hover { border-color: var(--border2); transform: translateY(-2px); }<\/p>\n<p>  .card-visual {\n    height: 180px;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    font-size: 64px;\n    position: relative;\n    overflow: hidden;\n  }\n  .card-visual::after {\n    content: '';\n    position: absolute;\n    inset: 0;\n    background: linear-gradient(to bottom, transparent 40%, rgba(22,22,22,0.9) 100%);\n  }<\/p>\n<p>  .badge {\n    position: absolute;\n    top: 12px;\n    left: 12px;\n    font-size: 10px;\n    font-weight: 600;\n    letter-spacing: 0.06em;\n    text-transform: uppercase;\n    padding: 4px 10px;\n    border-radius: 30px;\n    z-index: 1;\n  }\n  .badge-trending { background: rgba(245,166,35,0.2); color: var(--amber); border: 1px solid rgba(245,166,35,0.3); }\n  .badge-hidden { background: rgba(62,232,200,0.12); color: var(--teal); border: 1px solid rgba(62,232,200,0.25); }\n  .badge-popular { background: rgba(212,247,62,0.12); color: var(--accent); border: 1px solid rgba(212,247,62,0.25); }<\/p>\n<p>  .city-visual-bg {\n    position: absolute;\n    inset: 0;\n    opacity: 0.15;\n    font-size: 120px;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    filter: blur(8px);\n    transform: scale(1.1);\n  }<\/p>\n<p>  .card-body { padding: 18px 20px 20px; }\n  .card-header {\n    display: flex;\n    align-items: flex-start;\n    justify-content: space-between;\n    margin-bottom: 16px;\n  }\n  .city-name {\n    font-family: var(--font-display);\n    font-size: 19px;\n    font-weight: 700;\n    color: var(--text);\n    letter-spacing: -0.02em;\n    margin-bottom: 2px;\n  }\n  .city-meta { font-size: 12px; color: var(--text3); }<\/p>\n<p>  .score-pill {\n    display: flex;\n    flex-direction: column;\n    align-items: center;\n    background: var(--bg3);\n    border: 1px solid var(--border);\n    border-radius: 10px;\n    padding: 8px 14px;\n    min-width: 58px;\n    text-align: center;\n  }\n  .score-val { font-family: var(--font-display); font-size: 22px; font-weight: 700; line-height: 1; }\n  .score-lbl { font-size: 9px; color: var(--text3); text-transform: uppercase; letter-spacing: 0.08em; margin-top: 3px; }\n  .score-hi { color: var(--teal); }\n  .score-mid { color: var(--amber); }\n  .score-lo { color: var(--coral); }<\/p>\n<p>  .metrics-grid {\n    display: grid;\n    grid-template-columns: 1fr 1fr 1fr;\n    gap: 10px;\n    margin-bottom: 14px;\n  }\n  .metric {\n    background: var(--bg3);\n    border: 1px solid var(--border);\n    border-radius: var(--radius-sm);\n    padding: 10px 12px;\n  }\n  .metric-lbl {\n    font-size: 9px;\n    text-transform: uppercase;\n    letter-spacing: 0.08em;\n    color: var(--text3);\n    margin-bottom: 6px;\n    display: flex;\n    align-items: center;\n    gap: 4px;\n  }\n  .metric-lbl svg { width: 10px; height: 10px; opacity: 0.6; }\n  .metric-val {\n    font-family: var(--font-display);\n    font-size: 14px;\n    font-weight: 600;\n    color: var(--text);\n    line-height: 1;\n    margin-bottom: 6px;\n  }\n  .mini-bar { height: 2px; background: rgba(255,255,255,0.07); border-radius: 2px; overflow: hidden; }\n  .mini-bar-fill { height: 100%; border-radius: 2px; transition: width 0.4s ease; }\n  .bar-green { background: var(--teal); }\n  .bar-amber { background: var(--amber); }\n  .bar-red { background: var(--coral); }<\/p>\n<p>  .tags { display: flex; flex-wrap: wrap; gap: 6px; }\n  .tag {\n    font-size: 11px;\n    color: var(--text3);\n    background: var(--bg3);\n    border: 1px solid var(--border);\n    padding: 3px 10px;\n    border-radius: 30px;\n  }<\/p>\n<p>  .no-results { grid-column: 1 \/ -1; text-align: center; padding: 80px 20px; color: var(--text3); }\n  .no-results .nr-emoji { font-size: 48px; display: block; margin-bottom: 16px; }\n  .no-results p { font-size: 15px; }<\/p>\n<p>  .site-footer {\n    border-top: 1px solid var(--border);\n    padding: 30px 40px;\n    text-align: center;\n    font-size: 12px;\n    color: var(--text3);\n  }\n  .site-footer a { color: var(--text2); text-decoration: none; }\n  .site-footer a:hover { color: var(--accent); }<\/p>\n<p>  @media (max-width: 768px) {\n    .site-header { padding: 14px 20px; }\n    .hero { padding: 50px 20px 40px; }\n    .filters-section { padding: 20px; top: 49px; }\n    .filter-group { max-width: 100%; min-width: 140px; }\n    .results-section { padding: 28px 20px 60px; }\n    .grid { grid-template-columns: 1fr; }\n    .hero-stats { gap: 24px; }\n    .site-footer { padding: 20px; }\n  }\n<\/style>\n<p><\/head><br \/>\n<body><\/p>\n<header class=\"site-header\">\n  <a href=\"https:\/\/gonomadlife.com\" class=\"logo\">Go<span>Nomad<\/span>Life<\/a><br \/>\n  <span class=\"header-tag\">City Explorer<\/span><br \/>\n<\/header>\n<section class=\"hero\">\n<div class=\"hero-label\">Updated 2025<\/div>\n<h1>Best cities for<br \/><em>digital nomads<\/em><\/h1>\n<p class=\"hero-sub\">Find your next base. Filter by cost, internet, climate, safety and more \u2014 with real data on 30 cities worldwide.<\/p>\n<div class=\"hero-stats\">\n<div class=\"hero-stat\"><strong id=\"stat-cities\">30<\/strong><span>Cities ranked<\/span><\/div>\n<div class=\"hero-stat\"><strong>6<\/strong><span>Filter criteria<\/span><\/div>\n<div class=\"hero-stat\"><strong>$700<\/strong><span>Cheapest\/month<\/span><\/div>\n<\/p><\/div>\n<\/section>\n<section class=\"filters-section\">\n<div class=\"filters-inner\">\n<div class=\"filters-row\">\n<div class=\"filter-group\">\n        <label>Cost of living<\/label><br \/>\n        <select id=\"f-cost\"><option value=\"\">All budgets<\/option><option value=\"budget\">Budget (&lt;$1,500\/mo)<\/option><option value=\"mid\">Mid ($1,500\u2013$3,000)<\/option><option value=\"high\">High ($3,000+)<\/option><\/select>\n      <\/div>\n<div class=\"filter-group\">\n        <label>Internet speed<\/label><br \/>\n        <select id=\"f-internet\"><option value=\"\">Any speed<\/option><option value=\"fast\">Fast (50+ Mbps)<\/option><option value=\"ok\">Decent (20\u201350 Mbps)<\/option><\/select>\n      <\/div>\n<div class=\"filter-group\">\n        <label>Weather \/ climate<\/label><br \/>\n        <select id=\"f-weather\"><option value=\"\">Any climate<\/option><option value=\"tropical\">Tropical<\/option><option value=\"mediterranean\">Mediterranean<\/option><option value=\"temperate\">Temperate<\/option><option value=\"desert\">Dry \/ Desert<\/option><\/select>\n      <\/div>\n<div class=\"filter-group\">\n        <label>Safety<\/label><br \/>\n        <select id=\"f-safety\"><option value=\"\">Any<\/option><option value=\"high\">High safety (80+)<\/option><option value=\"mid\">Moderate (below 80)<\/option><\/select>\n      <\/div>\n<div class=\"filter-group\">\n        <label>Visa ease<\/label><br \/>\n        <select id=\"f-visa\"><option value=\"\">Any<\/option><option value=\"easy\">Easy \/ visa-free<\/option><option value=\"nomad\">Nomad visa available<\/option><\/select>\n      <\/div>\n<div class=\"filter-group\">\n        <label>Nightlife &amp; social<\/label><br \/>\n        <select id=\"f-night\"><option value=\"\">Any<\/option><option value=\"high\">Lively<\/option><option value=\"mid\">Moderate<\/option><option value=\"low\">Quiet \/ chill<\/option><\/select>\n      <\/div>\n<\/p><\/div>\n<div class=\"sort-row\">\n      <span class=\"sort-label\">Sort by:<\/span><br \/>\n      <button class=\"sort-btn active\" data-sort=\"score\">Nomad score<\/button><br \/>\n      <button class=\"sort-btn\" data-sort=\"cost\">Lowest cost<\/button><br \/>\n      <button class=\"sort-btn\" data-sort=\"internet\">Best internet<\/button><br \/>\n      <button class=\"sort-btn\" data-sort=\"safety\">Safest<\/button>\n    <\/div>\n<\/p><\/div>\n<\/section>\n<section class=\"results-section\">\n<div class=\"results-meta\">\n<p class=\"results-count\" id=\"results-count\"><strong>30<\/strong> destinations found<\/p>\n<\/p><\/div>\n<div class=\"grid\" id=\"grid\"><\/div>\n<\/section>\n<footer class=\"site-footer\">\n<p>Data curated by <a href=\"https:\/\/gonomadlife.com\">GoNomadLife.com<\/a> \u00b7 Scores based on community reports, cost indices, and internet speed data \u00b7 2025<\/p>\n<\/footer>\n<p><script>\nconst cities = [\n  { name:\"Chiang Mai\", country:\"Thailand\", flag:\"\ud83c\uddf9\ud83c\udded\", emoji:\"\ud83c\udfef\", badge:\"popular\", cost:\"budget\", costVal:950, internet:60, weather:\"tropical\", safety:\"mid\", safetyVal:72, visa:\"easy\", nightlife:\"mid\", nightVal:60, score:91, tags:[\"coworking\",\"cheap food\",\"temples\"] },\n  { name:\"Medell\u00edn\", country:\"Colombia\", flag:\"\ud83c\udde8\ud83c\uddf4\", emoji:\"\ud83c\udf38\", badge:\"trending\", cost:\"budget\", costVal:1100, internet:52, weather:\"temperate\", safety:\"mid\", safetyVal:60, visa:\"easy\", nightlife:\"high\", nightVal:88, score:89, tags:[\"eternal spring\",\"tech scene\",\"nomad visa\"] },\n  { name:\"Lisbon\", country:\"Portugal\", flag:\"\ud83c\uddf5\ud83c\uddf9\", emoji:\"\ud83c\udfd9\", badge:\"popular\", cost:\"mid\", costVal:2200, internet:80, weather:\"mediterranean\", safety:\"high\", safetyVal:85, visa:\"nomad\", nightlife:\"high\", nightVal:82, score:92, tags:[\"EU base\",\"English friendly\",\"surfing nearby\"] },\n  { name:\"Bali (Canggu)\", country:\"Indonesia\", flag:\"\ud83c\uddee\ud83c\udde9\", emoji:\"\ud83c\udf34\", badge:\"popular\", cost:\"budget\", costVal:1300, internet:42, weather:\"tropical\", safety:\"high\", safetyVal:80, visa:\"easy\", nightlife:\"high\", nightVal:85, score:90, tags:[\"beach vibes\",\"coworking\",\"yoga\"] },\n  { name:\"Tbilisi\", country:\"Georgia\", flag:\"\ud83c\uddec\ud83c\uddea\", emoji:\"\ud83c\udfd4\", badge:\"hidden\", cost:\"budget\", costVal:900, internet:55, weather:\"temperate\", safety:\"high\", safetyVal:88, visa:\"easy\", nightlife:\"high\", nightVal:80, score:88, tags:[\"1-year visa free\",\"cheap\",\"wine culture\"] },\n  { name:\"Barcelona\", country:\"Spain\", flag:\"\ud83c\uddea\ud83c\uddf8\", emoji:\"\ud83c\udfa8\", badge:\"popular\", cost:\"mid\", costVal:2600, internet:90, weather:\"mediterranean\", safety:\"high\", safetyVal:78, visa:\"nomad\", nightlife:\"high\", nightVal:95, score:87, tags:[\"EU base\",\"beaches\",\"architecture\"] },\n  { name:\"Mexico City\", country:\"Mexico\", flag:\"\ud83c\uddf2\ud83c\uddfd\", emoji:\"\ud83c\udf2e\", badge:\"trending\", cost:\"budget\", costVal:1400, internet:50, weather:\"temperate\", safety:\"mid\", safetyVal:55, visa:\"easy\", nightlife:\"high\", nightVal:90, score:86, tags:[\"food scene\",\"culture\",\"arts\"] },\n  { name:\"Budapest\", country:\"Hungary\", flag:\"\ud83c\udded\ud83c\uddfa\", emoji:\"\ud83c\udfdb\", badge:null, cost:\"budget\", costVal:1500, internet:75, weather:\"temperate\", safety:\"high\", safetyVal:84, visa:\"easy\", nightlife:\"high\", nightVal:88, score:85, tags:[\"thermal baths\",\"cheap EU\",\"ruin bars\"] },\n  { name:\"Porto\", country:\"Portugal\", flag:\"\ud83c\uddf5\ud83c\uddf9\", emoji:\"\ud83c\udf77\", badge:\"hidden\", cost:\"mid\", costVal:1900, internet:78, weather:\"mediterranean\", safety:\"high\", safetyVal:87, visa:\"nomad\", nightlife:\"mid\", nightVal:65, score:86, tags:[\"affordable\",\"charming\",\"slower pace\"] },\n  { name:\"Taipei\", country:\"Taiwan\", flag:\"\ud83c\uddf9\ud83c\uddfc\", emoji:\"\ud83c\udfd9\", badge:null, cost:\"mid\", costVal:1800, internet:95, weather:\"tropical\", safety:\"high\", safetyVal:92, visa:\"easy\", nightlife:\"mid\", nightVal:70, score:88, tags:[\"ultra-fast internet\",\"street food\",\"safety\"] },\n  { name:\"Playa del Carmen\", country:\"Mexico\", flag:\"\ud83c\uddf2\ud83c\uddfd\", emoji:\"\ud83c\udf0a\", badge:\"trending\", cost:\"budget\", costVal:1600, internet:45, weather:\"tropical\", safety:\"mid\", safetyVal:62, visa:\"easy\", nightlife:\"high\", nightVal:85, score:82, tags:[\"beach\",\"cenotes\",\"expat community\"] },\n  { name:\"Tallinn\", country:\"Estonia\", flag:\"\ud83c\uddea\ud83c\uddea\", emoji:\"\ud83c\udff0\", badge:\"hidden\", cost:\"mid\", costVal:1700, internet:88, weather:\"temperate\", safety:\"high\", safetyVal:89, visa:\"nomad\", nightlife:\"mid\", nightVal:68, score:84, tags:[\"e-residency\",\"old town\",\"startup hub\"] },\n  { name:\"Hoi An\", country:\"Vietnam\", flag:\"\ud83c\uddfb\ud83c\uddf3\", emoji:\"\ud83c\udfee\", badge:\"trending\", cost:\"budget\", costVal:700, internet:35, weather:\"tropical\", safety:\"high\", safetyVal:85, visa:\"easy\", nightlife:\"low\", nightVal:40, score:81, tags:[\"lanterns\",\"ultra cheap\",\"charming\"] },\n  { name:\"Tulum\", country:\"Mexico\", flag:\"\ud83c\uddf2\ud83c\uddfd\", emoji:\"\ud83c\udf3f\", badge:null, cost:\"mid\", costVal:2400, internet:38, weather:\"tropical\", safety:\"mid\", safetyVal:65, visa:\"easy\", nightlife:\"high\", nightVal:80, score:76, tags:[\"jungle vibes\",\"cenotes\",\"wellness\"] },\n  { name:\"Sarajevo\", country:\"Bosnia\", flag:\"\ud83c\udde7\ud83c\udde6\", emoji:\"\ud83d\udd4c\", badge:\"hidden\", cost:\"budget\", costVal:850, internet:50, weather:\"temperate\", safety:\"high\", safetyVal:82, visa:\"easy\", nightlife:\"mid\", nightVal:65, score:80, tags:[\"underrated\",\"culture\",\"cheap\"] },\n  { name:\"Kuala Lumpur\", country:\"Malaysia\", flag:\"\ud83c\uddf2\ud83c\uddfe\", emoji:\"\ud83c\udfd9\", badge:null, cost:\"budget\", costVal:1200, internet:65, weather:\"tropical\", safety:\"high\", safetyVal:76, visa:\"easy\", nightlife:\"mid\", nightVal:72, score:83, tags:[\"modern\",\"cheap flights hub\",\"halal food\"] },\n  { name:\"Cape Town\", country:\"South Africa\", flag:\"\ud83c\uddff\ud83c\udde6\", emoji:\"\ud83c\udfd4\", badge:null, cost:\"mid\", costVal:1600, internet:48, weather:\"mediterranean\", safety:\"mid\", safetyVal:52, visa:\"easy\", nightlife:\"high\", nightVal:78, score:79, tags:[\"mountains\",\"wine\",\"diverse food\"] },\n  { name:\"Athens\", country:\"Greece\", flag:\"\ud83c\uddec\ud83c\uddf7\", emoji:\"\ud83c\udffa\", badge:\"trending\", cost:\"mid\", costVal:1800, internet:55, weather:\"mediterranean\", safety:\"high\", safetyVal:80, visa:\"nomad\", nightlife:\"high\", nightVal:85, score:82, tags:[\"history\",\"EU base\",\"sunny\"] },\n  { name:\"Koh Lanta\", country:\"Thailand\", flag:\"\ud83c\uddf9\ud83c\udded\", emoji:\"\ud83c\udfdd\", badge:\"hidden\", cost:\"budget\", costVal:900, internet:30, weather:\"tropical\", safety:\"high\", safetyVal:88, visa:\"easy\", nightlife:\"low\", nightVal:35, score:78, tags:[\"slow life\",\"beaches\",\"zen\"] },\n  { name:\"Prague\", country:\"Czechia\", flag:\"\ud83c\udde8\ud83c\uddff\", emoji:\"\ud83c\udff0\", badge:null, cost:\"mid\", costVal:2000, internet:80, weather:\"temperate\", safety:\"high\", safetyVal:86, visa:\"easy\", nightlife:\"high\", nightVal:88, score:84, tags:[\"EU hub\",\"beautiful\",\"great nightlife\"] },\n  { name:\"Bogot\u00e1\", country:\"Colombia\", flag:\"\ud83c\udde8\ud83c\uddf4\", emoji:\"\ud83c\udf06\", badge:null, cost:\"budget\", costVal:1000, internet:55, weather:\"temperate\", safety:\"mid\", safetyVal:58, visa:\"easy\", nightlife:\"high\", nightVal:82, score:78, tags:[\"culture\",\"altitude\",\"food scene\"] },\n  { name:\"Chiang Rai\", country:\"Thailand\", flag:\"\ud83c\uddf9\ud83c\udded\", emoji:\"\ud83d\uded5\", badge:\"hidden\", cost:\"budget\", costVal:750, internet:30, weather:\"tropical\", safety:\"high\", safetyVal:90, visa:\"easy\", nightlife:\"low\", nightVal:30, score:76, tags:[\"temples\",\"nature\",\"slow pace\"] },\n  { name:\"Dubai\", country:\"UAE\", flag:\"\ud83c\udde6\ud83c\uddea\", emoji:\"\ud83c\udfd9\", badge:null, cost:\"high\", costVal:3800, internet:100, weather:\"desert\", safety:\"high\", safetyVal:95, visa:\"nomad\", nightlife:\"high\", nightVal:90, score:83, tags:[\"luxury\",\"0% tax\",\"modern\"] },\n  { name:\"Belgrade\", country:\"Serbia\", flag:\"\ud83c\uddf7\ud83c\uddf8\", emoji:\"\ud83c\udfdb\", badge:\"trending\", cost:\"budget\", costVal:1100, internet:65, weather:\"temperate\", safety:\"high\", safetyVal:82, visa:\"easy\", nightlife:\"high\", nightVal:95, score:83, tags:[\"nightlife capital\",\"cheap\",\"friendly\"] },\n  { name:\"Florian\u00f3polis\", country:\"Brazil\", flag:\"\ud83c\udde7\ud83c\uddf7\", emoji:\"\ud83c\udf0a\", badge:null, cost:\"mid\", costVal:1700, internet:48, weather:\"tropical\", safety:\"mid\", safetyVal:63, visa:\"easy\", nightlife:\"high\", nightVal:80, score:78, tags:[\"beaches\",\"surf\",\"warm people\"] },\n  { name:\"Split\", country:\"Croatia\", flag:\"\ud83c\udded\ud83c\uddf7\", emoji:\"\u26f5\", badge:\"trending\", cost:\"mid\", costVal:2100, internet:60, weather:\"mediterranean\", safety:\"high\", safetyVal:88, visa:\"nomad\", nightlife:\"mid\", nightVal:70, score:81, tags:[\"Adriatic\",\"old town\",\"EU access\"] },\n  { name:\"Ho Chi Minh City\", country:\"Vietnam\", flag:\"\ud83c\uddfb\ud83c\uddf3\", emoji:\"\ud83d\udef5\", badge:null, cost:\"budget\", costVal:800, internet:55, weather:\"tropical\", safety:\"high\", safetyVal:80, visa:\"easy\", nightlife:\"high\", nightVal:85, score:82, tags:[\"energy\",\"cheap\",\"amazing food\"] },\n  { name:\"Penang\", country:\"Malaysia\", flag:\"\ud83c\uddf2\ud83c\uddfe\", emoji:\"\ud83c\udfa8\", badge:\"hidden\", cost:\"budget\", costVal:1000, internet:60, weather:\"tropical\", safety:\"high\", safetyVal:82, visa:\"easy\", nightlife:\"mid\", nightVal:65, score:81, tags:[\"street art\",\"hawker food\",\"chill\"] },\n  { name:\"Kotor\", country:\"Montenegro\", flag:\"\ud83c\uddf2\ud83c\uddea\", emoji:\"\ud83c\udff0\", badge:\"hidden\", cost:\"mid\", costVal:1600, internet:45, weather:\"mediterranean\", safety:\"high\", safetyVal:88, visa:\"easy\", nightlife:\"low\", nightVal:45, score:77, tags:[\"medieval\",\"Adriatic\",\"hidden gem\"] }\n];<\/p>\n<p>const uniqueCities = cities.filter((c, i, arr) => arr.findIndex(x => x.name === c.name) === i);\nlet activeSort = \"score\";\nconst bgColors = [\"#1a1f12\",\"#12201e\",\"#1a1218\",\"#151a24\",\"#1e1a12\",\"#121a1a\",\"#1e1518\",\"#12181e\"];<\/p>\n<p>function getBg(name) {\n  let h = 0;\n  for(let i=0;i<name.length;i++) h = name.charCodeAt(i) + ((h<<5)-h);\n  return bgColors[Math.abs(h) % bgColors.length];\n}\nfunction barClass(val, low, high) {\n  if(val >= high) return \"bar-green\";\n  if(val >= low) return \"bar-amber\";\n  return \"bar-red\";\n}\nfunction scoreClass(s) {\n  if(s>=87) return \"score-hi\";\n  if(s>=80) return \"score-mid\";\n  return \"score-lo\";\n}\nfunction badgeHTML(b) {\n  if(!b) return \"\";\n  const map = { trending:[\"badge-trending\",\"Trending \u2191\"], hidden:[\"badge-hidden\",\"Hidden gem\"], popular:[\"badge-popular\",\"Popular\"] };\n  const [cls, lbl] = map[b];\n  return `<\/p>\n<div class=\"badge ${cls}\">${lbl}<\/div>\n<p>`;\n}<\/p>\n<p>function renderCard(c, idx) {\n  const costBarPct = Math.round(Math.max(0, (4200 - c.costVal) \/ 3700 * 100));\n  const costClass = c.costVal <= 1500 ? \"bar-green\" : c.costVal <= 2500 ? \"bar-amber\" : \"bar-red\";\n  const netClass = barClass(c.internet, 35, 55);\n  const safeClass = barClass(c.safetyVal, 65, 80);\n  const nightClass = barClass(c.nightVal, 50, 75);\n  const delay = Math.min(idx, 12) * 40;\n  return `\n\n\n<div class=\"card\" style=\"animation-delay:${delay}ms\">\n<div class=\"card-visual\" style=\"background:${getBg(c.name)}\">\n<div class=\"city-visual-bg\">${c.emoji}<\/div>\n<p>    <span style=\"position:relative;z-index:1;font-size:52px\">${c.emoji}<\/span>\n    ${badgeHTML(c.badge)}\n  <\/div>\n<div class=\"card-body\">\n<div class=\"card-header\">\n<div class=\"city-info\">\n<div class=\"city-name\">${c.name}<\/div>\n<div class=\"city-meta\">${c.flag} ${c.country}<\/div>\n<\/p><\/div>\n<div class=\"score-pill\">\n        <span class=\"score-val ${scoreClass(c.score)}\">${c.score}<\/span>\n        <span class=\"score-lbl\">score<\/span>\n      <\/div>\n<\/p><\/div>\n<div class=\"metrics-grid\">\n<div class=\"metric\">\n<div class=\"metric-lbl\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M12 2v20M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6\"\/><\/svg>Cost\/mo<\/div>\n<div class=\"metric-val\" style=\"color:${c.costVal<=1500?'var(--teal)':c.costVal<=2500?'var(--amber)':'var(--coral)'}\">$${c.costVal.toLocaleString()}<\/div>\n<div class=\"mini-bar\">\n<div class=\"mini-bar-fill ${costClass}\" style=\"width:${costBarPct}%\"><\/div>\n<\/div><\/div>\n<div class=\"metric\">\n<div class=\"metric-lbl\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M5 12.55a11 11 0 0 1 14.08 0M1.42 9a16 16 0 0 1 21.16 0M8.53 16.11a6 6 0 0 1 6.95 0M12 20h.01\"\/><\/svg>Internet<\/div>\n<div class=\"metric-val\">${c.internet}<span style=\"font-size:10px;font-weight:400;color:var(--text3)\"> Mbps<\/span><\/div>\n<div class=\"mini-bar\">\n<div class=\"mini-bar-fill ${netClass}\" style=\"width:${Math.round(c.internet)}%\"><\/div>\n<\/div><\/div>\n<div class=\"metric\">\n<div class=\"metric-lbl\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z\"\/><\/svg>Safety<\/div>\n<div class=\"metric-val\">${c.safetyVal}<span style=\"font-size:10px;font-weight:400;color:var(--text3)\">\/100<\/span><\/div>\n<div class=\"mini-bar\">\n<div class=\"mini-bar-fill ${safeClass}\" style=\"width:${c.safetyVal}%\"><\/div>\n<\/div><\/div>\n<div class=\"metric\">\n<div class=\"metric-lbl\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><circle cx=\"12\" cy=\"12\" r=\"5\"\/><line x1=\"12\" y1=\"1\" x2=\"12\" y2=\"3\"\/><line x1=\"12\" y1=\"21\" x2=\"12\" y2=\"23\"\/><line x1=\"4.22\" y1=\"4.22\" x2=\"5.64\" y2=\"5.64\"\/><line x1=\"18.36\" y1=\"18.36\" x2=\"19.78\" y2=\"19.78\"\/><line x1=\"1\" y1=\"12\" x2=\"3\" y2=\"12\"\/><line x1=\"21\" y1=\"12\" x2=\"23\" y2=\"12\"\/><line x1=\"4.22\" y1=\"19.78\" x2=\"5.64\" y2=\"18.36\"\/><line x1=\"18.36\" y1=\"5.64\" x2=\"19.78\" y2=\"4.22\"\/><\/svg>Climate<\/div>\n<div class=\"metric-val\" style=\"font-size:12px;font-weight:500\">${c.weather.charAt(0).toUpperCase()+c.weather.slice(1)}<\/div>\n<div class=\"mini-bar\">\n<div class=\"mini-bar-fill bar-green\" style=\"width:80%\"><\/div>\n<\/div><\/div>\n<div class=\"metric\">\n<div class=\"metric-lbl\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><rect x=\"2\" y=\"4\" width=\"20\" height=\"16\" rx=\"2\"\/><line x1=\"2\" y1=\"10\" x2=\"22\" y2=\"10\"\/><\/svg>Visa<\/div>\n<div class=\"metric-val\" style=\"font-size:11px;font-weight:500;color:${c.visa==='nomad'?'var(--teal)':'var(--text2)'}\">${c.visa===\"nomad\"?\"Nomad visa\":\"Visa free\"}<\/div>\n<div class=\"mini-bar\">\n<div class=\"mini-bar-fill ${c.visa==='nomad'?'bar-green':'bar-amber'}\" style=\"width:${c.visa==='nomad'?'100%':'65%'}\"><\/div>\n<\/div><\/div>\n<div class=\"metric\">\n<div class=\"metric-lbl\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M9 18V5l12-2v13\"\/><circle cx=\"6\" cy=\"18\" r=\"3\"\/><circle cx=\"18\" cy=\"16\" r=\"3\"\/><\/svg>Nightlife<\/div>\n<div class=\"metric-val\" style=\"font-size:12px;font-weight:500\">${c.nightlife.charAt(0).toUpperCase()+c.nightlife.slice(1)}<\/div>\n<div class=\"mini-bar\">\n<div class=\"mini-bar-fill ${nightClass}\" style=\"width:${c.nightVal}%\"><\/div>\n<\/div><\/div>\n<\/p><\/div>\n<div class=\"tags\">${c.tags.map(t=>`<span class=\"tag\">${t}<\/span>`).join(\"\")}<\/div>\n<\/p><\/div>\n<\/div>\n<p>`;\n}<\/p>\n<p>function applyFilters() {\n  const fCost = document.getElementById(\"f-cost\").value;\n  const fNet = document.getElementById(\"f-internet\").value;\n  const fWeather = document.getElementById(\"f-weather\").value;\n  const fSafety = document.getElementById(\"f-safety\").value;\n  const fVisa = document.getElementById(\"f-visa\").value;\n  const fNight = document.getElementById(\"f-night\").value;<\/p>\n<p>  let filtered = uniqueCities.filter(c => {\n    if(fCost === \"budget\" && c.cost !== \"budget\") return false;\n    if(fCost === \"mid\" && c.cost !== \"mid\") return false;\n    if(fCost === \"high\" && c.cost !== \"high\") return false;\n    if(fNet === \"fast\" && c.internet < 50) return false;\n    if(fNet === \"ok\" &#038;&#038; (c.internet < 20 || c.internet >= 50)) return false;\n    if(fWeather && c.weather !== fWeather) return false;\n    if(fSafety === \"high\" && c.safetyVal < 80) return false;\n    if(fSafety === \"mid\" &#038;&#038; c.safetyVal >= 80) return false;\n    if(fVisa === \"easy\" && c.visa !== \"easy\") return false;\n    if(fVisa === \"nomad\" && c.visa !== \"nomad\") return false;\n    if(fNight === \"high\" && c.nightlife !== \"high\") return false;\n    if(fNight === \"mid\" && c.nightlife !== \"mid\") return false;\n    if(fNight === \"low\" && c.nightlife !== \"low\") return false;\n    return true;\n  });<\/p>\n<p>  const sortFns = {\n    score: (a,b) => b.score - a.score,\n    cost: (a,b) => a.costVal - b.costVal,\n    internet: (a,b) => b.internet - a.internet,\n    safety: (a,b) => b.safetyVal - a.safetyVal\n  };\n  filtered.sort(sortFns[activeSort]);<\/p>\n<p>  const grid = document.getElementById(\"grid\");\n  const countEl = document.getElementById(\"results-count\");\n  countEl.innerHTML = `<strong>${filtered.length}<\/strong> destination${filtered.length !== 1 ? \"s\" : \"\"} found`;<\/p>\n<p>  if(filtered.length === 0) {\n    grid.innerHTML = `<\/p>\n<div class=\"no-results\"><span class=\"nr-emoji\">\ud83d\uddfa<\/span><\/p>\n<p>No cities match your filters.<br \/>Try adjusting your criteria.<\/p>\n<\/div>\n<p>`;\n  } else {\n    grid.innerHTML = filtered.map((c,i) => renderCard(c,i)).join(\"\");\n  }\n}<\/p>\n<p>document.querySelectorAll(\"select\").forEach(s => s.addEventListener(\"change\", applyFilters));\ndocument.querySelectorAll(\".sort-btn\").forEach(btn => {\n  btn.addEventListener(\"click\", () => {\n    document.querySelectorAll(\".sort-btn\").forEach(b => b.classList.remove(\"active\"));\n    btn.classList.add(\"active\");\n    activeSort = btn.dataset.sort;\n    applyFilters();\n  });\n});<\/p>\n<p>document.getElementById(\"stat-cities\").textContent = uniqueCities.length;\napplyFilters();\n<\/script><br \/>\n<\/body><br \/>\n<\/html><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Best Cities for Digital Nomads 2025 \u2014 Go Nomad Life GoNomadLife City Explorer Updated 2025 Best cities fordigital nomads Find your next base. Filter by cost, internet, climate, safety and more \u2014 with real data on 30 cities worldwide. 30Cities ranked 6Filter criteria $700Cheapest\/month Cost of living All budgetsBudget (&lt;$1,500\/mo)Mid ($1,500\u2013$3,000)High ($3,000+) Internet speed Any [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-445","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/gonomadlife.com\/index.php\/wp-json\/wp\/v2\/pages\/445","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/gonomadlife.com\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/gonomadlife.com\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/gonomadlife.com\/index.php\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/gonomadlife.com\/index.php\/wp-json\/wp\/v2\/comments?post=445"}],"version-history":[{"count":1,"href":"https:\/\/gonomadlife.com\/index.php\/wp-json\/wp\/v2\/pages\/445\/revisions"}],"predecessor-version":[{"id":446,"href":"https:\/\/gonomadlife.com\/index.php\/wp-json\/wp\/v2\/pages\/445\/revisions\/446"}],"wp:attachment":[{"href":"https:\/\/gonomadlife.com\/index.php\/wp-json\/wp\/v2\/media?parent=445"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}