[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"blog-author":3,"blog-sr-\u002Fblog\u002Fnuxt-cloudflare-workers-bindings":4},null,{"id":5,"title":6,"author":3,"body":7,"createdAt":1837,"description":1838,"draft":1839,"extension":1840,"image":1841,"meta":1844,"navigation":419,"path":1845,"readingTime":151,"seo":1846,"sitemap":1847,"stem":1848,"tags":1849,"updatedAt":1837,"__hash__":1854},"blog_sr\u002Fblog\u002Fnuxt-cloudflare-workers-bindings.md","Nuxt 3 na Cloudflare Workers: kako ispravno podesiti bindings",{"type":8,"value":9,"toc":1825},"minimark",[10,15,19,31,35,53,164,263,298,302,305,374,377,557,564,939,942,1232,1243,1250,1253,1277,1299,1397,1420,1424,1449,1452,1509,1524,1530,1537,1559,1566,1614,1621,1625,1632,1665,1668,1735,1745,1751,1755,1815,1821],[11,12,14],"h2",{"id":13},"jedna-stvar-zbog-koje-se-workers-isplati","Jedna stvar zbog koje se Workers isplati",[16,17,18],"p",{},"Nuxt aplikaciju možete hostovati skoro bilo gde. Razlog da je stavite na Cloudflare Workers nije CDN — već bindings. KV namespace, D1 baza, R2 bucket ili Durable Object predati vašim server rutama kao živ objekat, bez connection stringa, bez poolinga i bez cold-start rukovanja.",[16,20,21,22,26,27,30],{},"Kvaka je u tome što bindings ne postoje u Node.js svetu u kome Nuxt inače radi. Oni stižu po zahtevu, zakačeni za Workers izvršni kontekst. Dovesti ih do vaših ",[23,24,25],"code",{},"server\u002Fapi"," handlera — i naterati ih da rade u ",[23,28,29],{},"nuxt dev"," — prvi je pravi deo instalacija u svakom Nuxt 3 + Workers projektu.",[11,32,34],{"id":33},"podesite-preset-i-wrangler-fajl","Podesite preset i Wrangler fajl",[16,36,37,38,41,42,45,46,49,50,52],{},"Nitro ima dva Cloudflare cilja koja su bitna. ",[23,39,40],{},"cloudflare_module"," gradi Worker sa ulaznom tačkom u stilu modula (",[23,43,44],{},"export default { fetch }",") i servira vaš statički izlaz kroz Workers Assets binding. ",[23,47,48],{},"cloudflare-pages"," cilja Pages Functions. Za nove projekte, birajte ",[23,51,40],{},": Workers Assets je ono u šta Cloudflare ulaže, a dobijate i pun skup Worker mogućnosti (Durable Objects, cron okidače, redove) umesto podskupa koji nudi Pages.",[54,55,60],"pre",{"className":56,"code":57,"language":58,"meta":59,"style":59},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u002F\u002F nuxt.config.ts\nexport default defineNuxtConfig({\n  modules: ['nitro-cloudflare-dev'],\n  nitro: {\n    preset: 'cloudflare_module',\n  },\n})\n","ts","",[23,61,62,71,93,121,132,149,155],{"__ignoreMap":59},[63,64,67],"span",{"class":65,"line":66},"line",1,[63,68,70],{"class":69},"sHwdD","\u002F\u002F nuxt.config.ts\n",[63,72,74,78,81,85,89],{"class":65,"line":73},2,[63,75,77],{"class":76},"s7zQu","export",[63,79,80],{"class":76}," default",[63,82,84],{"class":83},"s2Zo4"," defineNuxtConfig",[63,86,88],{"class":87},"sTEyZ","(",[63,90,92],{"class":91},"sMK4o","{\n",[63,94,96,100,103,106,109,113,115,118],{"class":65,"line":95},3,[63,97,99],{"class":98},"swJcz","  modules",[63,101,102],{"class":91},":",[63,104,105],{"class":87}," [",[63,107,108],{"class":91},"'",[63,110,112],{"class":111},"sfazB","nitro-cloudflare-dev",[63,114,108],{"class":91},[63,116,117],{"class":87},"]",[63,119,120],{"class":91},",\n",[63,122,124,127,129],{"class":65,"line":123},4,[63,125,126],{"class":98},"  nitro",[63,128,102],{"class":91},[63,130,131],{"class":91}," {\n",[63,133,135,138,140,143,145,147],{"class":65,"line":134},5,[63,136,137],{"class":98},"    preset",[63,139,102],{"class":91},[63,141,142],{"class":91}," '",[63,144,40],{"class":111},[63,146,108],{"class":91},[63,148,120],{"class":91},[63,150,152],{"class":65,"line":151},6,[63,153,154],{"class":91},"  },\n",[63,156,158,161],{"class":65,"line":157},7,[63,159,160],{"class":91},"}",[63,162,163],{"class":87},")\n",[54,165,169],{"className":166,"code":167,"language":168,"meta":59,"style":59},"language-jsonc shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u002F\u002F wrangler.jsonc\n{\n  \"name\": \"nuxt-cf-starter\",\n  \"main\": \".\u002F.output\u002Fserver\u002Findex.mjs\",\n  \"compatibility_date\": \"2025-04-01\",\n  \"compatibility_flags\": [\"nodejs_compat\"],\n  \"assets\": {\n    \"directory\": \".\u002F.output\u002Fpublic\u002F\",\n    \"binding\": \"ASSETS\",\n  },\n  \"kv_namespaces\": [\n    { \"binding\": \"CACHE\", \"id\": \"3f9c...\", \"preview_id\": \"8a12...\" },\n  ],\n  \"d1_databases\": [\n    { \"binding\": \"DB\", \"database_name\": \"app\", \"database_id\": \"b41e...\" },\n  ],\n}\n","jsonc",[23,170,171,176,180,185,190,195,200,205,211,217,222,228,234,240,246,252,257],{"__ignoreMap":59},[63,172,173],{"class":65,"line":66},[63,174,175],{},"\u002F\u002F wrangler.jsonc\n",[63,177,178],{"class":65,"line":73},[63,179,92],{},[63,181,182],{"class":65,"line":95},[63,183,184],{},"  \"name\": \"nuxt-cf-starter\",\n",[63,186,187],{"class":65,"line":123},[63,188,189],{},"  \"main\": \".\u002F.output\u002Fserver\u002Findex.mjs\",\n",[63,191,192],{"class":65,"line":134},[63,193,194],{},"  \"compatibility_date\": \"2025-04-01\",\n",[63,196,197],{"class":65,"line":151},[63,198,199],{},"  \"compatibility_flags\": [\"nodejs_compat\"],\n",[63,201,202],{"class":65,"line":157},[63,203,204],{},"  \"assets\": {\n",[63,206,208],{"class":65,"line":207},8,[63,209,210],{},"    \"directory\": \".\u002F.output\u002Fpublic\u002F\",\n",[63,212,214],{"class":65,"line":213},9,[63,215,216],{},"    \"binding\": \"ASSETS\",\n",[63,218,220],{"class":65,"line":219},10,[63,221,154],{},[63,223,225],{"class":65,"line":224},11,[63,226,227],{},"  \"kv_namespaces\": [\n",[63,229,231],{"class":65,"line":230},12,[63,232,233],{},"    { \"binding\": \"CACHE\", \"id\": \"3f9c...\", \"preview_id\": \"8a12...\" },\n",[63,235,237],{"class":65,"line":236},13,[63,238,239],{},"  ],\n",[63,241,243],{"class":65,"line":242},14,[63,244,245],{},"  \"d1_databases\": [\n",[63,247,249],{"class":65,"line":248},15,[63,250,251],{},"    { \"binding\": \"DB\", \"database_name\": \"app\", \"database_id\": \"b41e...\" },\n",[63,253,255],{"class":65,"line":254},16,[63,256,239],{},[63,258,260],{"class":65,"line":259},17,[63,261,262],{},"}\n",[16,264,265,266,269,270,273,274,277,278,281,282,285,286,289,290,293,294,297],{},"Dve napomene o tom fajlu. ",[23,267,268],{},"nodejs_compat"," je gotovo uvek neophodan — Nitro izlaz, i većina npm paketa koje ćete uvući, očekuju da postoje ",[23,271,272],{},"node:buffer",", ",[23,275,276],{},"node:crypto"," ili ",[23,279,280],{},"node:async_hooks",". I ",[23,283,284],{},"main"," pokazuje na rezultat build-a, pa ",[23,287,288],{},"nuxt build"," mora da se izvrši pre ",[23,291,292],{},"wrangler deploy",". Skripta ",[23,295,296],{},"\"deploy\": \"nuxt build && wrangler deploy\""," drži to pod kontrolom.",[11,299,301],{"id":300},"čitanje-bindings-a-unutar-server-rute","Čitanje bindings-a unutar server rute",[16,303,304],{},"Nitro izlaže Workers okruženje na H3 event objektu:",[54,306,308],{"className":56,"code":307,"language":58,"meta":59,"style":59},"event.context.cloudflare.env \u002F\u002F vaši bindings + vars + secrets\nevent.context.cloudflare.context \u002F\u002F ExecutionContext (waitUntil, passThroughOnException)\nevent.context.cloudflare.request \u002F\u002F sirovi Request\n",[23,309,310,334,354],{"__ignoreMap":59},[63,311,312,315,318,321,323,326,328,331],{"class":65,"line":66},[63,313,314],{"class":87},"event",[63,316,317],{"class":91},".",[63,319,320],{"class":87},"context",[63,322,317],{"class":91},[63,324,325],{"class":87},"cloudflare",[63,327,317],{"class":91},[63,329,330],{"class":87},"env ",[63,332,333],{"class":69},"\u002F\u002F vaši bindings + vars + secrets\n",[63,335,336,338,340,342,344,346,348,351],{"class":65,"line":73},[63,337,314],{"class":87},[63,339,317],{"class":91},[63,341,320],{"class":87},[63,343,317],{"class":91},[63,345,325],{"class":87},[63,347,317],{"class":91},[63,349,350],{"class":87},"context ",[63,352,353],{"class":69},"\u002F\u002F ExecutionContext (waitUntil, passThroughOnException)\n",[63,355,356,358,360,362,364,366,368,371],{"class":65,"line":95},[63,357,314],{"class":87},[63,359,317],{"class":91},[63,361,320],{"class":87},[63,363,317],{"class":91},[63,365,325],{"class":87},[63,367,317],{"class":91},[63,369,370],{"class":87},"request ",[63,372,373],{"class":69},"\u002F\u002F sirovi Request\n",[16,375,376],{},"Umotajte taj pristup jednom, tako da svaka ruta pukne na isti način kada nešto nije dobro podešeno:",[54,378,380],{"className":56,"code":379,"language":58,"meta":59,"style":59},"\u002F\u002F server\u002Futils\u002Fcloudflare.ts\nimport type { H3Event } from 'h3'\n\nexport function cf(event: H3Event) {\n  const cloudflare = event.context.cloudflare\n  if (!cloudflare) {\n    throw createError({\n      statusCode: 500,\n      statusMessage:\n        'Cloudflare bindings unavailable — is nitro-cloudflare-dev enabled?',\n    })\n  }\n  return cloudflare\n}\n",[23,381,382,387,415,421,447,470,488,500,513,521,533,540,545,553],{"__ignoreMap":59},[63,383,384],{"class":65,"line":66},[63,385,386],{"class":69},"\u002F\u002F server\u002Futils\u002Fcloudflare.ts\n",[63,388,389,392,395,398,401,404,407,409,412],{"class":65,"line":73},[63,390,391],{"class":76},"import",[63,393,394],{"class":76}," type",[63,396,397],{"class":91}," {",[63,399,400],{"class":87}," H3Event",[63,402,403],{"class":91}," }",[63,405,406],{"class":76}," from",[63,408,142],{"class":91},[63,410,411],{"class":111},"h3",[63,413,414],{"class":91},"'\n",[63,416,417],{"class":65,"line":95},[63,418,420],{"emptyLinePlaceholder":419},true,"\n",[63,422,423,425,429,432,434,437,439,442,445],{"class":65,"line":123},[63,424,77],{"class":76},[63,426,428],{"class":427},"spNyl"," function",[63,430,431],{"class":83}," cf",[63,433,88],{"class":91},[63,435,314],{"class":436},"sHdIc",[63,438,102],{"class":91},[63,440,400],{"class":441},"sBMFI",[63,443,444],{"class":91},")",[63,446,131],{"class":91},[63,448,449,452,455,458,461,463,465,467],{"class":65,"line":134},[63,450,451],{"class":427},"  const",[63,453,454],{"class":87}," cloudflare",[63,456,457],{"class":91}," =",[63,459,460],{"class":87}," event",[63,462,317],{"class":91},[63,464,320],{"class":87},[63,466,317],{"class":91},[63,468,469],{"class":87},"cloudflare\n",[63,471,472,475,478,481,483,486],{"class":65,"line":151},[63,473,474],{"class":76},"  if",[63,476,477],{"class":98}," (",[63,479,480],{"class":91},"!",[63,482,325],{"class":87},[63,484,485],{"class":98},") ",[63,487,92],{"class":91},[63,489,490,493,496,498],{"class":65,"line":157},[63,491,492],{"class":76},"    throw",[63,494,495],{"class":83}," createError",[63,497,88],{"class":98},[63,499,92],{"class":91},[63,501,502,505,507,511],{"class":65,"line":207},[63,503,504],{"class":98},"      statusCode",[63,506,102],{"class":91},[63,508,510],{"class":509},"sbssI"," 500",[63,512,120],{"class":91},[63,514,515,518],{"class":65,"line":213},[63,516,517],{"class":98},"      statusMessage",[63,519,520],{"class":91},":\n",[63,522,523,526,529,531],{"class":65,"line":219},[63,524,525],{"class":91},"        '",[63,527,528],{"class":111},"Cloudflare bindings unavailable — is nitro-cloudflare-dev enabled?",[63,530,108],{"class":91},[63,532,120],{"class":91},[63,534,535,538],{"class":65,"line":224},[63,536,537],{"class":91},"    }",[63,539,163],{"class":98},[63,541,542],{"class":65,"line":230},[63,543,544],{"class":91},"  }\n",[63,546,547,550],{"class":65,"line":236},[63,548,549],{"class":76},"  return",[63,551,552],{"class":87}," cloudflare\n",[63,554,555],{"class":65,"line":242},[63,556,262],{"class":91},[16,558,559,560,563],{},"Keš baziran na KV-u za spor upstream API, uz ",[23,561,562],{},"waitUntil"," da upis ne blokira odgovor:",[54,565,567],{"className":56,"code":566,"language":58,"meta":59,"style":59},"\u002F\u002F server\u002Fapi\u002Frates.get.ts\nexport default defineEventHandler(async (event) => {\n  const { env, context } = cf(event)\n  const key = 'rates:usd'\n\n  const cached = await env.CACHE.get(key, 'json')\n  if (cached) {\n    setHeader(event, 'x-cache', 'HIT')\n    return cached\n  }\n\n  const fresh = await $fetch\u003C{ base: string; rates: Record\u003Cstring, number> }>(\n    'https:\u002F\u002Fapi.example.com\u002Fv1\u002Frates\u002Fusd',\n  )\n\n  context.waitUntil(\n    env.CACHE.put(key, JSON.stringify(fresh), { expirationTtl: 300 }),\n  )\n\n  setHeader(event, 'x-cache', 'MISS')\n  return fresh\n})\n",[23,568,569,574,599,626,642,646,686,699,728,736,740,744,800,812,817,821,832,885,890,895,924,932],{"__ignoreMap":59},[63,570,571],{"class":65,"line":66},[63,572,573],{"class":69},"\u002F\u002F server\u002Fapi\u002Frates.get.ts\n",[63,575,576,578,580,583,585,588,590,592,594,597],{"class":65,"line":73},[63,577,77],{"class":76},[63,579,80],{"class":76},[63,581,582],{"class":83}," defineEventHandler",[63,584,88],{"class":87},[63,586,587],{"class":427},"async",[63,589,477],{"class":91},[63,591,314],{"class":436},[63,593,444],{"class":91},[63,595,596],{"class":427}," =>",[63,598,131],{"class":91},[63,600,601,603,605,608,611,614,616,618,620,622,624],{"class":65,"line":95},[63,602,451],{"class":427},[63,604,397],{"class":91},[63,606,607],{"class":87}," env",[63,609,610],{"class":91},",",[63,612,613],{"class":87}," context",[63,615,403],{"class":91},[63,617,457],{"class":91},[63,619,431],{"class":83},[63,621,88],{"class":98},[63,623,314],{"class":87},[63,625,163],{"class":98},[63,627,628,630,633,635,637,640],{"class":65,"line":123},[63,629,451],{"class":427},[63,631,632],{"class":87}," key",[63,634,457],{"class":91},[63,636,142],{"class":91},[63,638,639],{"class":111},"rates:usd",[63,641,414],{"class":91},[63,643,644],{"class":65,"line":134},[63,645,420],{"emptyLinePlaceholder":419},[63,647,648,650,653,655,658,660,662,665,667,670,672,675,677,679,682,684],{"class":65,"line":151},[63,649,451],{"class":427},[63,651,652],{"class":87}," cached",[63,654,457],{"class":91},[63,656,657],{"class":76}," await",[63,659,607],{"class":87},[63,661,317],{"class":91},[63,663,664],{"class":87},"CACHE",[63,666,317],{"class":91},[63,668,669],{"class":83},"get",[63,671,88],{"class":98},[63,673,674],{"class":87},"key",[63,676,610],{"class":91},[63,678,142],{"class":91},[63,680,681],{"class":111},"json",[63,683,108],{"class":91},[63,685,163],{"class":98},[63,687,688,690,692,695,697],{"class":65,"line":157},[63,689,474],{"class":76},[63,691,477],{"class":98},[63,693,694],{"class":87},"cached",[63,696,485],{"class":98},[63,698,92],{"class":91},[63,700,701,704,706,708,710,712,715,717,719,721,724,726],{"class":65,"line":207},[63,702,703],{"class":83},"    setHeader",[63,705,88],{"class":98},[63,707,314],{"class":87},[63,709,610],{"class":91},[63,711,142],{"class":91},[63,713,714],{"class":111},"x-cache",[63,716,108],{"class":91},[63,718,610],{"class":91},[63,720,142],{"class":91},[63,722,723],{"class":111},"HIT",[63,725,108],{"class":91},[63,727,163],{"class":98},[63,729,730,733],{"class":65,"line":213},[63,731,732],{"class":76},"    return",[63,734,735],{"class":87}," cached\n",[63,737,738],{"class":65,"line":219},[63,739,544],{"class":91},[63,741,742],{"class":65,"line":224},[63,743,420],{"emptyLinePlaceholder":419},[63,745,746,748,751,753,755,758,761,764,766,769,772,775,777,780,783,786,788,791,794,797],{"class":65,"line":230},[63,747,451],{"class":427},[63,749,750],{"class":87}," fresh",[63,752,457],{"class":91},[63,754,657],{"class":76},[63,756,757],{"class":83}," $fetch",[63,759,760],{"class":91},"\u003C{",[63,762,763],{"class":98}," base",[63,765,102],{"class":91},[63,767,768],{"class":441}," string",[63,770,771],{"class":91},";",[63,773,774],{"class":98}," rates",[63,776,102],{"class":91},[63,778,779],{"class":441}," Record",[63,781,782],{"class":91},"\u003C",[63,784,785],{"class":441},"string",[63,787,610],{"class":91},[63,789,790],{"class":441}," number",[63,792,793],{"class":91},">",[63,795,796],{"class":91}," }>",[63,798,799],{"class":98},"(\n",[63,801,802,805,808,810],{"class":65,"line":236},[63,803,804],{"class":91},"    '",[63,806,807],{"class":111},"https:\u002F\u002Fapi.example.com\u002Fv1\u002Frates\u002Fusd",[63,809,108],{"class":91},[63,811,120],{"class":91},[63,813,814],{"class":65,"line":242},[63,815,816],{"class":98},"  )\n",[63,818,819],{"class":65,"line":248},[63,820,420],{"emptyLinePlaceholder":419},[63,822,823,826,828,830],{"class":65,"line":254},[63,824,825],{"class":87},"  context",[63,827,317],{"class":91},[63,829,562],{"class":83},[63,831,799],{"class":98},[63,833,834,837,839,841,843,846,848,850,852,855,857,860,862,865,867,869,871,874,876,879,881,883],{"class":65,"line":259},[63,835,836],{"class":87},"    env",[63,838,317],{"class":91},[63,840,664],{"class":87},[63,842,317],{"class":91},[63,844,845],{"class":83},"put",[63,847,88],{"class":98},[63,849,674],{"class":87},[63,851,610],{"class":91},[63,853,854],{"class":87}," JSON",[63,856,317],{"class":91},[63,858,859],{"class":83},"stringify",[63,861,88],{"class":98},[63,863,864],{"class":87},"fresh",[63,866,444],{"class":98},[63,868,610],{"class":91},[63,870,397],{"class":91},[63,872,873],{"class":98}," expirationTtl",[63,875,102],{"class":91},[63,877,878],{"class":509}," 300",[63,880,403],{"class":91},[63,882,444],{"class":98},[63,884,120],{"class":91},[63,886,888],{"class":65,"line":887},18,[63,889,816],{"class":98},[63,891,893],{"class":65,"line":892},19,[63,894,420],{"emptyLinePlaceholder":419},[63,896,898,901,903,905,907,909,911,913,915,917,920,922],{"class":65,"line":897},20,[63,899,900],{"class":83},"  setHeader",[63,902,88],{"class":98},[63,904,314],{"class":87},[63,906,610],{"class":91},[63,908,142],{"class":91},[63,910,714],{"class":111},[63,912,108],{"class":91},[63,914,610],{"class":91},[63,916,142],{"class":91},[63,918,919],{"class":111},"MISS",[63,921,108],{"class":91},[63,923,163],{"class":98},[63,925,927,929],{"class":65,"line":926},21,[63,928,549],{"class":76},[63,930,931],{"class":87}," fresh\n",[63,933,935,937],{"class":65,"line":934},22,[63,936,160],{"class":91},[63,938,163],{"class":87},[16,940,941],{},"I D1, koji koristi pripremljene izraze sa pozicionim vezivanjem parametara:",[54,943,945],{"className":56,"code":944,"language":58,"meta":59,"style":59},"\u002F\u002F server\u002Fapi\u002Fposts.get.ts\ninterface PostRow {\n  id: number\n  title: string\n  created_at: string\n}\n\nexport default defineEventHandler(async (event) => {\n  const { env } = cf(event)\n  const { limit = '20' } = getQuery\u003C{ limit?: string }>(event)\n\n  const { results } = await env.DB.prepare(\n    `select id, title, created_at\n         from posts\n        where published = 1\n        order by created_at desc\n        limit ?1`,\n  )\n    .bind(Math.min(Number(limit) || 20, 100))\n    .all\u003CPostRow>()\n\n  return results\n})\n",[23,946,947,952,962,972,982,991,995,999,1021,1041,1083,1087,1116,1124,1129,1134,1139,1149,1153,1197,1214,1218,1225],{"__ignoreMap":59},[63,948,949],{"class":65,"line":66},[63,950,951],{"class":69},"\u002F\u002F server\u002Fapi\u002Fposts.get.ts\n",[63,953,954,957,960],{"class":65,"line":73},[63,955,956],{"class":427},"interface",[63,958,959],{"class":441}," PostRow",[63,961,131],{"class":91},[63,963,964,967,969],{"class":65,"line":95},[63,965,966],{"class":98},"  id",[63,968,102],{"class":91},[63,970,971],{"class":441}," number\n",[63,973,974,977,979],{"class":65,"line":123},[63,975,976],{"class":98},"  title",[63,978,102],{"class":91},[63,980,981],{"class":441}," string\n",[63,983,984,987,989],{"class":65,"line":134},[63,985,986],{"class":98},"  created_at",[63,988,102],{"class":91},[63,990,981],{"class":441},[63,992,993],{"class":65,"line":151},[63,994,262],{"class":91},[63,996,997],{"class":65,"line":157},[63,998,420],{"emptyLinePlaceholder":419},[63,1000,1001,1003,1005,1007,1009,1011,1013,1015,1017,1019],{"class":65,"line":207},[63,1002,77],{"class":76},[63,1004,80],{"class":76},[63,1006,582],{"class":83},[63,1008,88],{"class":87},[63,1010,587],{"class":427},[63,1012,477],{"class":91},[63,1014,314],{"class":436},[63,1016,444],{"class":91},[63,1018,596],{"class":427},[63,1020,131],{"class":91},[63,1022,1023,1025,1027,1029,1031,1033,1035,1037,1039],{"class":65,"line":213},[63,1024,451],{"class":427},[63,1026,397],{"class":91},[63,1028,607],{"class":87},[63,1030,403],{"class":91},[63,1032,457],{"class":91},[63,1034,431],{"class":83},[63,1036,88],{"class":98},[63,1038,314],{"class":87},[63,1040,163],{"class":98},[63,1042,1043,1045,1047,1050,1052,1054,1057,1059,1061,1063,1066,1068,1070,1073,1075,1077,1079,1081],{"class":65,"line":219},[63,1044,451],{"class":427},[63,1046,397],{"class":91},[63,1048,1049],{"class":87}," limit",[63,1051,457],{"class":91},[63,1053,142],{"class":91},[63,1055,1056],{"class":111},"20",[63,1058,108],{"class":91},[63,1060,403],{"class":91},[63,1062,457],{"class":91},[63,1064,1065],{"class":83}," getQuery",[63,1067,760],{"class":91},[63,1069,1049],{"class":98},[63,1071,1072],{"class":91},"?:",[63,1074,768],{"class":441},[63,1076,796],{"class":91},[63,1078,88],{"class":98},[63,1080,314],{"class":87},[63,1082,163],{"class":98},[63,1084,1085],{"class":65,"line":224},[63,1086,420],{"emptyLinePlaceholder":419},[63,1088,1089,1091,1093,1096,1098,1100,1102,1104,1106,1109,1111,1114],{"class":65,"line":230},[63,1090,451],{"class":427},[63,1092,397],{"class":91},[63,1094,1095],{"class":87}," results",[63,1097,403],{"class":91},[63,1099,457],{"class":91},[63,1101,657],{"class":76},[63,1103,607],{"class":87},[63,1105,317],{"class":91},[63,1107,1108],{"class":87},"DB",[63,1110,317],{"class":91},[63,1112,1113],{"class":83},"prepare",[63,1115,799],{"class":98},[63,1117,1118,1121],{"class":65,"line":236},[63,1119,1120],{"class":91},"    `",[63,1122,1123],{"class":111},"select id, title, created_at\n",[63,1125,1126],{"class":65,"line":242},[63,1127,1128],{"class":111},"         from posts\n",[63,1130,1131],{"class":65,"line":248},[63,1132,1133],{"class":111},"        where published = 1\n",[63,1135,1136],{"class":65,"line":254},[63,1137,1138],{"class":111},"        order by created_at desc\n",[63,1140,1141,1144,1147],{"class":65,"line":259},[63,1142,1143],{"class":111},"        limit ?1",[63,1145,1146],{"class":91},"`",[63,1148,120],{"class":91},[63,1150,1151],{"class":65,"line":887},[63,1152,816],{"class":98},[63,1154,1155,1158,1161,1163,1166,1168,1171,1173,1176,1178,1181,1183,1186,1189,1191,1194],{"class":65,"line":892},[63,1156,1157],{"class":91},"    .",[63,1159,1160],{"class":83},"bind",[63,1162,88],{"class":98},[63,1164,1165],{"class":87},"Math",[63,1167,317],{"class":91},[63,1169,1170],{"class":83},"min",[63,1172,88],{"class":98},[63,1174,1175],{"class":83},"Number",[63,1177,88],{"class":98},[63,1179,1180],{"class":87},"limit",[63,1182,485],{"class":98},[63,1184,1185],{"class":91},"||",[63,1187,1188],{"class":509}," 20",[63,1190,610],{"class":91},[63,1192,1193],{"class":509}," 100",[63,1195,1196],{"class":98},"))\n",[63,1198,1199,1201,1204,1206,1209,1211],{"class":65,"line":897},[63,1200,1157],{"class":91},[63,1202,1203],{"class":83},"all",[63,1205,782],{"class":91},[63,1207,1208],{"class":441},"PostRow",[63,1210,793],{"class":91},[63,1212,1213],{"class":98},"()\n",[63,1215,1216],{"class":65,"line":926},[63,1217,420],{"emptyLinePlaceholder":419},[63,1219,1220,1222],{"class":65,"line":934},[63,1221,549],{"class":76},[63,1223,1224],{"class":87}," results\n",[63,1226,1228,1230],{"class":65,"line":1227},23,[63,1229,160],{"class":91},[63,1231,163],{"class":87},[16,1233,1234,1235,1238,1239,1242],{},"Ovde nikada nemojte graditi SQL nadovezivanjem stringova. D1 podržava ",[23,1236,1237],{},".batch()"," za više izraza u jednom odlasku do baze, što je važnije nego što biste pomislili: svaki ",[23,1240,1241],{},"await"," prema D1 je mrežni skok od lokacije vašeg Worker-a do primarnog regiona baze.",[11,1244,1246,1247],{"id":1245},"kako-dobiti-tipove-umesto-any","Kako dobiti tipove umesto ",[23,1248,1249],{},"any",[16,1251,1252],{},"Wrangler generiše tipove iz vaše konfiguracije. Dodajte to u svoj dev tok:",[54,1254,1258],{"className":1255,"code":1256,"language":1257,"meta":59,"style":59},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","npx wrangler types --env-interface CloudflareEnv\n","bash",[23,1259,1260],{"__ignoreMap":59},[63,1261,1262,1265,1268,1271,1274],{"class":65,"line":66},[63,1263,1264],{"class":441},"npx",[63,1266,1267],{"class":111}," wrangler",[63,1269,1270],{"class":111}," types",[63,1272,1273],{"class":111}," --env-interface",[63,1275,1276],{"class":111}," CloudflareEnv\n",[16,1278,1279,1280,1283,1284,1287,1288,273,1291,1294,1295,1298],{},"To upisuje ",[23,1281,1282],{},"worker-configuration.d.ts"," koji sadrži interfejs ",[23,1285,1286],{},"CloudflareEnv"," sa ",[23,1289,1290],{},"CACHE: KVNamespace",[23,1292,1293],{},"DB: D1Database"," i svakim ",[23,1296,1297],{},"var"," koji ste deklarisali. Povežite ga sa event kontekstom:",[54,1300,1302],{"className":56,"code":1301,"language":58,"meta":59,"style":59},"\u002F\u002F server\u002Ftypes\u002Fh3.d.ts\ndeclare module 'h3' {\n  interface H3EventContext {\n    cloudflare: {\n      request: Request\n      env: CloudflareEnv\n      context: ExecutionContext\n    }\n  }\n}\n\nexport {}\n",[23,1303,1304,1309,1325,1335,1344,1354,1363,1373,1378,1382,1386,1390],{"__ignoreMap":59},[63,1305,1306],{"class":65,"line":66},[63,1307,1308],{"class":69},"\u002F\u002F server\u002Ftypes\u002Fh3.d.ts\n",[63,1310,1311,1314,1317,1319,1321,1323],{"class":65,"line":73},[63,1312,1313],{"class":427},"declare",[63,1315,1316],{"class":427}," module",[63,1318,142],{"class":91},[63,1320,411],{"class":111},[63,1322,108],{"class":91},[63,1324,131],{"class":91},[63,1326,1327,1330,1333],{"class":65,"line":95},[63,1328,1329],{"class":427},"  interface",[63,1331,1332],{"class":441}," H3EventContext",[63,1334,131],{"class":91},[63,1336,1337,1340,1342],{"class":65,"line":123},[63,1338,1339],{"class":98},"    cloudflare",[63,1341,102],{"class":91},[63,1343,131],{"class":91},[63,1345,1346,1349,1351],{"class":65,"line":134},[63,1347,1348],{"class":98},"      request",[63,1350,102],{"class":91},[63,1352,1353],{"class":441}," Request\n",[63,1355,1356,1359,1361],{"class":65,"line":151},[63,1357,1358],{"class":98},"      env",[63,1360,102],{"class":91},[63,1362,1276],{"class":441},[63,1364,1365,1368,1370],{"class":65,"line":157},[63,1366,1367],{"class":98},"      context",[63,1369,102],{"class":91},[63,1371,1372],{"class":441}," ExecutionContext\n",[63,1374,1375],{"class":65,"line":207},[63,1376,1377],{"class":91},"    }\n",[63,1379,1380],{"class":65,"line":213},[63,1381,544],{"class":91},[63,1383,1384],{"class":65,"line":219},[63,1385,262],{"class":91},[63,1387,1388],{"class":65,"line":224},[63,1389,420],{"emptyLinePlaceholder":419},[63,1391,1392,1394],{"class":65,"line":230},[63,1393,77],{"class":76},[63,1395,1396],{"class":91}," {}\n",[16,1398,1399,1400,1403,1404,1407,1408,1411,1412,1415,1416,1419],{},"Sada ",[23,1401,1402],{},"env.DB.prepare()"," ima autodopunu, a slovna greška u imenu binding-a postaje greška pri build-u. Ponovo pokrenite ",[23,1405,1406],{},"wrangler types"," kad god izmenite ",[23,1409,1410],{},"wrangler.jsonc"," — ",[23,1413,1414],{},"postinstall"," skripta ili prefiks u ",[23,1417,1418],{},"dev"," skripti su uobičajena mesta za to.",[11,1421,1423],{"id":1422},"lokalni-razvoj-koji-zaista-koristi-bindings","Lokalni razvoj koji zaista koristi bindings",[16,1425,1426,1428,1429,1432,1433,1435,1436,1439,1440,1443,1444,1448],{},[23,1427,112],{}," poziva Wrangler-ov ",[23,1430,1431],{},"getPlatformProxy()"," i ubacuje prave bindings u ",[23,1434,29],{},". Iza njih stoji Miniflare (isti ",[23,1437,1438],{},"workerd"," runtime koji Cloudflare pokreće u produkciji), sa stanjem koje se čuva u ",[23,1441,1442],{},".wrangler\u002Fstate",". Dakle, lokalni KV je prava KV implementacija, a lokalni D1 je pravi SQLite fajl — ali ",[1445,1446,1447],"em",{},"drugačiji"," od produkcionog.",[16,1450,1451],{},"To znači da migracije morate primeniti dvaput:",[54,1453,1455],{"className":1255,"code":1454,"language":1257,"meta":59,"style":59},"# lokalni sqlite koji koristi nuxt dev\nnpx wrangler d1 migrations apply app --local\n\n# prava baza\nnpx wrangler d1 migrations apply app --remote\n",[23,1456,1457,1462,1483,1487,1492],{"__ignoreMap":59},[63,1458,1459],{"class":65,"line":66},[63,1460,1461],{"class":69},"# lokalni sqlite koji koristi nuxt dev\n",[63,1463,1464,1466,1468,1471,1474,1477,1480],{"class":65,"line":73},[63,1465,1264],{"class":441},[63,1467,1267],{"class":111},[63,1469,1470],{"class":111}," d1",[63,1472,1473],{"class":111}," migrations",[63,1475,1476],{"class":111}," apply",[63,1478,1479],{"class":111}," app",[63,1481,1482],{"class":111}," --local\n",[63,1484,1485],{"class":65,"line":95},[63,1486,420],{"emptyLinePlaceholder":419},[63,1488,1489],{"class":65,"line":123},[63,1490,1491],{"class":69},"# prava baza\n",[63,1493,1494,1496,1498,1500,1502,1504,1506],{"class":65,"line":134},[63,1495,1264],{"class":441},[63,1497,1267],{"class":111},[63,1499,1470],{"class":111},[63,1501,1473],{"class":111},[63,1503,1476],{"class":111},[63,1505,1479],{"class":111},[63,1507,1508],{"class":111}," --remote\n",[16,1510,1511,1512,1515,1516,1519,1520,1523],{},"Dodajte ",[23,1513,1514],{},".wrangler"," u ",[23,1517,1518],{},".gitignore",". Kada treba da debagujete nad produkcionim podacima, ",[23,1521,1522],{},"wrangler dev --remote"," pokreće vaš izgrađeni Worker uz prave udaljene bindings — korisno, ali i vrlo dobar način da slučajno pišete u produkciju. Držite to u namenskoj, jasno imenovanoj skripti.",[16,1525,1526,1527,1529],{},"Kompromis kod ",[23,1528,112],{},": dodaje drugi runtime u vaš dev proces, pa je pokretanje sporije, a mali broj Vite\u002FNitro rubnih slučajeva ponaša se drugačije nego u Nuxt-ovom podrazumevanom Node dev serveru. Alternativa je da ga preskočite i da čuvate svaki pristup binding-u, čime menjate par sekundi pokretanja za „radi lokalno, 500 u produkciji“. Uzmite sporije pokretanje.",[11,1531,1533,1534],{"id":1532},"secrets-vars-i-useruntimeconfig","Secrets, vars i ",[23,1535,1536],{},"useRuntimeConfig",[16,1538,1539,1540,1542,1543,1546,1547,1550,1551,1554,1555,1558],{},"Vrednosti koje nisu tajne idu u ",[23,1541,1410],{}," pod ",[23,1544,1545],{},"\"vars\"",". Tajne idu u ",[23,1548,1549],{},"wrangler secret put API_TOKEN"," i nikada ne dodiruju repozitorijum. Oboje završavaju na ",[23,1552,1553],{},"env"," — ne na ",[23,1556,1557],{},"process.env",", koji na Workers-u jedva postoji.",[16,1560,1561,1562,1565],{},"Ako koristite ",[23,1563,1564],{},"runtimeConfig",", ovaj detalj će vas ujesti tačno jednom:",[54,1567,1569],{"className":56,"code":1568,"language":58,"meta":59,"style":59},"\u002F\u002F ✅ env override-i (NUXT_*) se primenjuju\nconst config = useRuntimeConfig(event)\n\n\u002F\u002F ❌ na Workers-u vraća samo podrazumevane vrednosti iz build-a\nconst config = useRuntimeConfig()\n",[23,1570,1571,1576,1593,1597,1602],{"__ignoreMap":59},[63,1572,1573],{"class":65,"line":66},[63,1574,1575],{"class":69},"\u002F\u002F ✅ env override-i (NUXT_*) se primenjuju\n",[63,1577,1578,1581,1584,1587,1590],{"class":65,"line":73},[63,1579,1580],{"class":427},"const",[63,1582,1583],{"class":87}," config ",[63,1585,1586],{"class":91},"=",[63,1588,1589],{"class":83}," useRuntimeConfig",[63,1591,1592],{"class":87},"(event)\n",[63,1594,1595],{"class":65,"line":95},[63,1596,420],{"emptyLinePlaceholder":419},[63,1598,1599],{"class":65,"line":123},[63,1600,1601],{"class":69},"\u002F\u002F ❌ na Workers-u vraća samo podrazumevane vrednosti iz build-a\n",[63,1603,1604,1606,1608,1610,1612],{"class":65,"line":134},[63,1605,1580],{"class":427},[63,1607,1583],{"class":87},[63,1609,1586],{"class":91},[63,1611,1589],{"class":83},[63,1613,1213],{"class":87},[16,1615,1616,1617,1620],{},"Pošto je okruženje vezano za zahtev, Nitro može da primeni override-e sa ",[23,1618,1619],{},"NUXT_"," prefiksom samo kada vidi event. Uvek ga prosledite.",[11,1622,1624],{"id":1623},"šta-ne-raditi","Šta ne raditi",[16,1626,1627,1631],{},[1628,1629,1630],"strong",{},"Ne dirajte bindings na nivou modula."," Ovo izgleda u redu, a pokvareno je:",[54,1633,1635],{"className":56,"code":1634,"language":58,"meta":59,"style":59},"\u002F\u002F server\u002Futils\u002Fdb.ts — NEMOJTE OVO DA RADITE\nconst db = useCloudflareEnv().DB \u002F\u002F nema zahteva, nema env-a\n",[23,1636,1637,1642],{"__ignoreMap":59},[63,1638,1639],{"class":65,"line":66},[63,1640,1641],{"class":69},"\u002F\u002F server\u002Futils\u002Fdb.ts — NEMOJTE OVO DA RADITE\n",[63,1643,1644,1646,1649,1651,1654,1657,1659,1662],{"class":65,"line":73},[63,1645,1580],{"class":427},[63,1647,1648],{"class":87}," db ",[63,1650,1586],{"class":91},[63,1652,1653],{"class":83}," useCloudflareEnv",[63,1655,1656],{"class":87},"()",[63,1658,317],{"class":91},[63,1660,1661],{"class":87},"DB ",[63,1663,1664],{"class":69},"\u002F\u002F nema zahteva, nema env-a\n",[16,1666,1667],{},"Inicijalizacija modula dešava se jednom po izolatu, pre nego što bilo koji zahtev postoji. Umesto toga, prosledite event (ili env) niz sloj za podatke. Ako koristite Drizzle, to znači da klijenta pravite po zahtevu — jeftino je, pošto nema konekcije koju treba otvarati:",[54,1669,1671],{"className":56,"code":1670,"language":58,"meta":59,"style":59},"export function useDb(event: H3Event) {\n  return drizzle(cf(event).env.DB, { schema })\n}\n",[23,1672,1673,1694,1731],{"__ignoreMap":59},[63,1674,1675,1677,1679,1682,1684,1686,1688,1690,1692],{"class":65,"line":66},[63,1676,77],{"class":76},[63,1678,428],{"class":427},[63,1680,1681],{"class":83}," useDb",[63,1683,88],{"class":91},[63,1685,314],{"class":436},[63,1687,102],{"class":91},[63,1689,400],{"class":441},[63,1691,444],{"class":91},[63,1693,131],{"class":91},[63,1695,1696,1698,1701,1703,1706,1708,1710,1712,1714,1716,1718,1720,1722,1724,1727,1729],{"class":65,"line":73},[63,1697,549],{"class":76},[63,1699,1700],{"class":83}," drizzle",[63,1702,88],{"class":98},[63,1704,1705],{"class":83},"cf",[63,1707,88],{"class":98},[63,1709,314],{"class":87},[63,1711,444],{"class":98},[63,1713,317],{"class":91},[63,1715,1553],{"class":87},[63,1717,317],{"class":91},[63,1719,1108],{"class":87},[63,1721,610],{"class":91},[63,1723,397],{"class":91},[63,1725,1726],{"class":87}," schema",[63,1728,403],{"class":91},[63,1730,163],{"class":98},[63,1732,1733],{"class":65,"line":95},[63,1734,262],{"class":91},[16,1736,1737,1740,1741,1744],{},[1628,1738,1739],{},"Ne keširajte vrednosti vezane za zahtev u promenljivama na nivou modula."," Izolati se ponovo koriste između zahteva različitih korisnika. ",[23,1742,1743],{},"let currentUser"," na nivou modula je curenje podataka.",[16,1746,1747,1750],{},[1628,1748,1749],{},"Ne posežite za KV-om kao za bazom."," KV je eventually consistent — upisu može trebati do oko minut da postane vidljiv svuda, a čitanja se keširaju na edge-u sa minimalnim TTL-om od 60 sekundi. Odličan je za konfiguraciju, feature flag-ove, sesije i keširanje renderovanih fragmenata. Pogrešan je za bilo šta gde čitate odmah nakon upisa. Za to postoji D1 (relaciona, jedan primarni region, opcione read replike) ili Durable Object (jaka konzistentnost, jedna nit po instanci).",[11,1752,1754],{"id":1753},"kontrolna-lista-koja-radi","Kontrolna lista koja radi",[1756,1757,1758,1772,1781,1791,1798,1809],"ol",{},[1759,1760,1761,1764,1765,1767,1768,1771],"li",{},[23,1762,1763],{},"nitro.preset = 'cloudflare_module'",", uključen ",[23,1766,268],{},", deklarisan ",[23,1769,1770],{},"assets"," binding.",[1759,1773,1774,1775,1777,1778,1780],{},"Bindings deklarisani u ",[23,1776,1410],{},"; ",[23,1779,1406],{}," pokrenut i uključen u korak provere tipova.",[1759,1782,1783,1515,1785,273,1788,1790],{},[23,1784,112],{},[23,1786,1787],{},"modules",[23,1789,1514],{}," u gitignore-u.",[1759,1792,1793,1794,1797],{},"Jedan ",[23,1795,1796],{},"cf(event)"," helper; nikakav pristup binding-ima na nivou modula.",[1759,1799,1800,1801,1804,1805,1808],{},"Odvojene ",[23,1802,1803],{},"--local"," i ",[23,1806,1807],{},"--remote"," skripte za migracije.",[1759,1810,1811,1814],{},[23,1812,1813],{},"useRuntimeConfig(event)"," svuda, uvek sa event objektom.",[16,1816,1817,1818,1820],{},"Uradite tih šest stvari kako treba i ostatak Workers platforme — redovi, cron okidači, Durable Objects, R2 — samo je još jedan unos u istom konfiguracionom fajlu i još jedno svojstvo na istom ",[23,1819,1553],{}," objektu.",[1822,1823,1824],"style",{},"html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}",{"title":59,"searchDepth":73,"depth":73,"links":1826},[1827,1828,1829,1830,1832,1833,1835,1836],{"id":13,"depth":73,"text":14},{"id":33,"depth":73,"text":34},{"id":300,"depth":73,"text":301},{"id":1245,"depth":73,"text":1831},"Kako dobiti tipove umesto any",{"id":1422,"depth":73,"text":1423},{"id":1532,"depth":73,"text":1834},"Secrets, vars i useRuntimeConfig",{"id":1623,"depth":73,"text":1624},{"id":1753,"depth":73,"text":1754},"2026-08-10","Kako povezati KV, D1 i R2 bindings sa Nuxt 3 server rutama na Cloudflare Workers — tipizirani env, lokalni Miniflare razvoj i greške koje ruše produkciju.",false,"md",{"src":1842,"alt":1843},"https:\u002F\u002Fimagedelivery.net\u002FcUFrXwQQ4FworoGhQKTMlw\u002F6157f2b7-8c1b-41b3-218c-5692d538fb00\u002Fw=1200,h=630,fit=cover","Izometrijska ilustracija užarenog serverskog bloka sa tri obojena modula za skladištenje koji su na njega priključeni snopovima svetlosti, na tamnoj mreži u pozadini.",{},"\u002Fblog\u002Fnuxt-cloudflare-workers-bindings",{"title":6,"description":1838},{"loc":1845,"lastmod":1837},"blog\u002Fnuxt-cloudflare-workers-bindings",[1850,325,1851,1852,1853],"nuxt","workers","d1","kv","cPpPZWIOsdoY8DnS3DeHro2hEIB9Ty0bugdd7a00KHM"]