[{"data":1,"prerenderedAt":1912},["ShallowReactive",2],{"navigation":3,"/docs/blob":137,"/docs/blob-surround":1907},[4,123],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":113},"Docs","i-lucide-book","/docs","docs",[10,34,58,73,84,95,114],{"title":11,"path":12,"stem":13,"children":14,"icon":33},"Getting Started","/docs/getting-started","docs/1.getting-started/1.index",[15,17,21,25,29],{"title":16,"path":12,"stem":13},"Introduction",{"title":18,"path":19,"stem":20},"Installation","/docs/getting-started/installation","docs/1.getting-started/2.installation",{"title":22,"path":23,"stem":24},"Deploy","/docs/getting-started/deploy","docs/1.getting-started/3.deploy",{"title":26,"path":27,"stem":28},"Migration","/docs/getting-started/migration","docs/1.getting-started/4.migration",{"title":30,"path":31,"stem":32},"Environments","/docs/getting-started/environments","docs/1.getting-started/5.environments","i-lucide-rocket",{"title":35,"path":36,"stem":37,"children":38,"icon":57},"Database","/docs/database","docs/2.database/1.index",[39,41,45,49,53],{"title":40,"path":36,"stem":37},"Setup",{"title":42,"path":43,"stem":44},"Schema","/docs/database/schema","docs/2.database/2.schema",{"title":46,"path":47,"stem":48},"Queries","/docs/database/query","docs/2.database/3.query",{"title":50,"path":51,"stem":52},"Migrations","/docs/database/migrations","docs/2.database/4.migrations",{"title":54,"path":55,"stem":56},"CLI","/docs/database/cli","docs/2.database/cli","i-lucide-database",{"title":59,"path":60,"stem":61,"children":62,"icon":72},"Blob","/docs/blob","docs/3.blob/1.index",[63,64,68],{"title":40,"path":60,"stem":61},{"title":65,"path":66,"stem":67},"Upload","/docs/blob/upload","docs/3.blob/2.upload",{"title":69,"path":70,"stem":71},"Blob SDK","/docs/blob/usage","docs/3.blob/3.usage","i-lucide-shapes",{"title":74,"path":75,"stem":76,"children":77,"icon":83},"Key Value","/docs/kv","docs/4.kv/1.index",[78,79],{"title":40,"path":75,"stem":76},{"title":80,"path":81,"stem":82},"KV SDK","/docs/kv/usage","docs/4.kv/2.usage","i-lucide-list",{"title":85,"path":86,"stem":87,"children":88,"icon":94},"Cache","/docs/cache","docs/5.cache/1.index",[89,90],{"title":40,"path":86,"stem":87},{"title":91,"path":92,"stem":93},"Usage","/docs/cache/usage","docs/5.cache/2.usage","i-lucide-zap",{"title":96,"icon":97,"path":98,"stem":99,"children":100,"page":113},"Guides","i-lucide-book-text","/docs/guides","docs/6.guides",[101,105,109],{"title":102,"path":103,"stem":104},"Pre-rendering","/docs/guides/pre-rendering","docs/6.guides/1.pre-rendering",{"title":106,"path":107,"stem":108},"Realtime","/docs/guides/realtime","docs/6.guides/2.realtime",{"title":110,"path":111,"stem":112},"CI/CD","/docs/guides/ci-cd","docs/6.guides/3.ci-cd",false,{"title":115,"path":116,"stem":117,"children":118,"page":113},"Reference","/docs/reference","docs/7.reference",[119],{"title":120,"path":121,"stem":122},"Environment Variables","/docs/reference/environment-variables","docs/7.reference/1.environment-variables",{"title":124,"icon":125,"path":126,"stem":127,"children":128,"page":113},"Changelog","i-lucide-megaphone","/changelog","changelog",[129,133],{"title":130,"path":131,"stem":132},"NuxtHub Multi-Vendor is now available","/changelog/nuxthub-multi-vendor","changelog/nuxthub-multi-vendor",{"title":134,"path":135,"stem":136},"Self-Hosting First & Cloud-Agnostic Future","/changelog/self-hosting-first","changelog/self-hosting-first",{"id":138,"title":139,"body":140,"description":1900,"extension":1901,"links":1902,"meta":1903,"navigation":1904,"path":60,"seo":1905,"stem":61,"__hash__":1906},"docs/docs/3.blob/1.index.md","Nuxt Blob Storage",{"type":141,"value":142,"toc":1886},"minimark",[143,147,706,710,716,857,860,1257,1261,1271,1882],[144,145,11],"h2",{"id":146},"getting-started",[148,149,151,156,165,239,243,246,254,620,624,631,702],"steps",{"level":150},"3",[152,153,155],"h3",{"id":154},"enable-blob-storage","Enable blob storage",[157,158,159,160,164],"p",{},"Enable blob storage in your project by setting ",[161,162,163],"code",{},"blob: true"," in the NuxtHub config.",[166,167,173],"pre",{"className":168,"code":169,"filename":170,"language":171,"meta":172,"style":172},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","export default defineNuxtConfig({\n  hub: {\n    blob: true\n  }\n})\n","nuxt.config.ts","ts","",[161,174,175,199,212,224,230],{"__ignoreMap":172},[176,177,180,184,187,191,195],"span",{"class":178,"line":179},"line",1,[176,181,183],{"class":182},"s7zQu","export",[176,185,186],{"class":182}," default",[176,188,190],{"class":189},"s2Zo4"," defineNuxtConfig",[176,192,194],{"class":193},"sTEyZ","(",[176,196,198],{"class":197},"sMK4o","{\n",[176,200,202,206,209],{"class":178,"line":201},2,[176,203,205],{"class":204},"swJcz","  hub",[176,207,208],{"class":197},":",[176,210,211],{"class":197}," {\n",[176,213,215,218,220],{"class":178,"line":214},3,[176,216,217],{"class":204},"    blob",[176,219,208],{"class":197},[176,221,223],{"class":222},"sfNiH"," true\n",[176,225,227],{"class":178,"line":226},4,[176,228,229],{"class":197},"  }\n",[176,231,233,236],{"class":178,"line":232},5,[176,234,235],{"class":197},"}",[176,237,238],{"class":193},")\n",[152,240,242],{"id":241},"set-a-driver","Set a driver",[157,244,245],{},"NuxtHub automatically configures the blob storage driver based on your environment variables or hosting provider.",[247,248,249,250,253],"note",{},"By default, if NuxtHub cannot detect a driver, files are stored locally in the ",[161,251,252],{},".data/blob"," directory.",[255,256,258,363,459,518],"tabs",{"sync":257},"blob-provider",[259,260,263,270,359],"tabs-item",{"icon":261,"label":262},"i-simple-icons-nodedotjs","FS (default)",[157,264,265,266,269],{},"To set the storage directory, you can set the ",[161,267,268],{},"dir"," option.",[166,271,273],{"className":168,"code":272,"filename":170,"language":171,"meta":172,"style":172},"export default defineNuxtConfig({\n  hub: {\n    blob: {\n      driver: 'fs',\n      dir: '.data/my-blob-directory' // Defaults to `.data/blob`\n    }\n  }\n})\n",[161,274,275,287,295,303,323,341,347,352],{"__ignoreMap":172},[176,276,277,279,281,283,285],{"class":178,"line":179},[176,278,183],{"class":182},[176,280,186],{"class":182},[176,282,190],{"class":189},[176,284,194],{"class":193},[176,286,198],{"class":197},[176,288,289,291,293],{"class":178,"line":201},[176,290,205],{"class":204},[176,292,208],{"class":197},[176,294,211],{"class":197},[176,296,297,299,301],{"class":178,"line":214},[176,298,217],{"class":204},[176,300,208],{"class":197},[176,302,211],{"class":197},[176,304,305,308,310,313,317,320],{"class":178,"line":226},[176,306,307],{"class":204},"      driver",[176,309,208],{"class":197},[176,311,312],{"class":197}," '",[176,314,316],{"class":315},"sfazB","fs",[176,318,319],{"class":197},"'",[176,321,322],{"class":197},",\n",[176,324,325,328,330,332,335,337],{"class":178,"line":232},[176,326,327],{"class":204},"      dir",[176,329,208],{"class":197},[176,331,312],{"class":197},[176,333,334],{"class":315},".data/my-blob-directory",[176,336,319],{"class":197},[176,338,340],{"class":339},"sHwdD"," // Defaults to `.data/blob`\n",[176,342,344],{"class":178,"line":343},6,[176,345,346],{"class":197},"    }\n",[176,348,350],{"class":178,"line":349},7,[176,351,229],{"class":197},[176,353,355,357],{"class":178,"line":354},8,[176,356,235],{"class":197},[176,358,238],{"class":193},[360,361,362],"important",{},"The local filesystem driver is not suitable for production environments.",[259,364,367,378,389,392,397],{"icon":365,"label":366},"i-simple-icons-amazons3","S3",[157,368,369,370,377],{},"To configure ",[371,372,376],"a",{"href":373,"rel":374},"https://aws.amazon.com/s3/",[375],"nofollow","Amazon S3"," as a blob storage driver.",[379,380,381],"ol",{},[382,383,384,385,388],"li",{},"Install the ",[161,386,387],{},"aws4fetch"," package",[390,391],"pm-install",{"name":387},[379,393,394],{"start":201},[382,395,396],{},"Set the following environment variables:",[166,398,403],{"className":399,"code":400,"filename":401,"language":402,"meta":172,"style":172},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","S3_ACCESS_KEY_ID=your-access-key-id\nS3_SECRET_ACCESS_KEY=your-secret-access-key\nS3_BUCKET=your-bucket-name\nS3_REGION=your-region\nS3_ENDPOINT=your-endpoint # (optional)\n",".env","bash",[161,404,405,416,426,436,446],{"__ignoreMap":172},[176,406,407,410,413],{"class":178,"line":179},[176,408,409],{"class":193},"S3_ACCESS_KEY_ID",[176,411,412],{"class":197},"=",[176,414,415],{"class":315},"your-access-key-id\n",[176,417,418,421,423],{"class":178,"line":201},[176,419,420],{"class":193},"S3_SECRET_ACCESS_KEY",[176,422,412],{"class":197},[176,424,425],{"class":315},"your-secret-access-key\n",[176,427,428,431,433],{"class":178,"line":214},[176,429,430],{"class":193},"S3_BUCKET",[176,432,412],{"class":197},[176,434,435],{"class":315},"your-bucket-name\n",[176,437,438,441,443],{"class":178,"line":226},[176,439,440],{"class":193},"S3_REGION",[176,442,412],{"class":197},[176,444,445],{"class":315},"your-region\n",[176,447,448,451,453,456],{"class":178,"line":232},[176,449,450],{"class":193},"S3_ENDPOINT",[176,452,412],{"class":197},[176,454,455],{"class":315},"your-endpoint",[176,457,458],{"class":339}," # (optional)\n",[259,460,463,472,479,481,492,495,504],{"icon":461,"label":462},"i-simple-icons-vercel","Vercel Blob",[157,464,465,466,471],{},"When deploying to Vercel, it automatically configures ",[371,467,470],{"href":468,"rel":469},"https://vercel.com/docs/storage/vercel-blob",[375],"Vercel Blob Storage",".",[379,473,474],{},[382,475,384,476,388],{},[161,477,478],{},"@vercel/blob",[390,480],{"name":478},[379,482,483],{"start":201},[382,484,485,486,491],{},"Assign a Vercel Blob Store to your project from the ",[371,487,490],{"href":488,"rel":489},"https://vercel.com/",[375],"Vercel dashboard"," -> Project -> Storage",[360,493,494],{},"Files stored in Vercel Blob are always public. Manually configure a different storage driver if storing sensitive files.",[379,496,497],{"start":214},[382,498,499,500,503],{},"When running locally, you can set the ",[161,501,502],{},"BLOB_READ_WRITE_TOKEN"," environment variable to enable the Vercel Blob driver:",[166,505,507],{"className":399,"code":506,"filename":401,"language":402,"meta":172,"style":172},"BLOB_READ_WRITE_TOKEN=your-token\n",[161,508,509],{"__ignoreMap":172},[176,510,511,513,515],{"class":178,"line":179},[176,512,502],{"class":193},[176,514,412],{"class":197},[176,516,517],{"class":315},"your-token\n",[259,519,522,530,607,612],{"icon":520,"label":521},"i-simple-icons-cloudflare","Cloudflare R2",[157,523,524,525,529],{},"When deploying to Cloudflare, configure ",[371,526,521],{"href":527,"rel":528},"https://developers.cloudflare.com/r2/",[375]," by providing the bucket name. NuxtHub auto-generates the wrangler bindings at build time.",[166,531,533],{"className":168,"code":532,"filename":170,"language":171,"meta":172,"style":172},"export default defineNuxtConfig({\n  hub: {\n    blob: {\n      driver: 'cloudflare-r2',\n      bucketName: '\u003Cbucket-name>'\n    }\n  }\n})\n",[161,534,535,547,555,563,578,593,597,601],{"__ignoreMap":172},[176,536,537,539,541,543,545],{"class":178,"line":179},[176,538,183],{"class":182},[176,540,186],{"class":182},[176,542,190],{"class":189},[176,544,194],{"class":193},[176,546,198],{"class":197},[176,548,549,551,553],{"class":178,"line":201},[176,550,205],{"class":204},[176,552,208],{"class":197},[176,554,211],{"class":197},[176,556,557,559,561],{"class":178,"line":214},[176,558,217],{"class":204},[176,560,208],{"class":197},[176,562,211],{"class":197},[176,564,565,567,569,571,574,576],{"class":178,"line":226},[176,566,307],{"class":204},[176,568,208],{"class":197},[176,570,312],{"class":197},[176,572,573],{"class":315},"cloudflare-r2",[176,575,319],{"class":197},[176,577,322],{"class":197},[176,579,580,583,585,587,590],{"class":178,"line":232},[176,581,582],{"class":204},"      bucketName",[176,584,208],{"class":197},[176,586,312],{"class":197},[176,588,589],{"class":315},"\u003Cbucket-name>",[176,591,592],{"class":197},"'\n",[176,594,595],{"class":178,"line":343},[176,596,346],{"class":197},[176,598,599],{"class":178,"line":349},[176,600,229],{"class":197},[176,602,603,605],{"class":178,"line":354},[176,604,235],{"class":197},[176,606,238],{"class":193},[608,609,611],"callout",{"to":610},"https://developers.cloudflare.com/r2/api/workers/workers-api-usage/","Learn more about R2 bindings on Cloudflare's documentation.",[247,613,614,615,471],{},"To use Cloudflare R2 without hosting on Cloudflare Workers, use the ",[371,616,619],{"href":617,"rel":618},"https://developers.cloudflare.com/r2/api/s3/api/",[375],"Cloudflare R2 via S3 API",[152,621,623],{"id":622},"upload-a-file","Upload a file",[157,625,626,627,630],{},"To upload a file, you can use the ",[161,628,629],{},"blob.put()"," method.",[166,632,634],{"className":168,"code":633,"language":171,"meta":172,"style":172},"import { blob } from 'hub:blob'\n\nconst file = await blob.put('avatars/user-1.png', imageData)\n",[161,635,636,660,666],{"__ignoreMap":172},[176,637,638,641,644,647,650,653,655,658],{"class":178,"line":179},[176,639,640],{"class":182},"import",[176,642,643],{"class":197}," {",[176,645,646],{"class":193}," blob",[176,648,649],{"class":197}," }",[176,651,652],{"class":182}," from",[176,654,312],{"class":197},[176,656,657],{"class":315},"hub:blob",[176,659,592],{"class":197},[176,661,662],{"class":178,"line":201},[176,663,665],{"emptyLinePlaceholder":664},true,"\n",[176,667,668,672,675,677,680,682,684,687,689,691,694,696,699],{"class":178,"line":214},[176,669,671],{"class":670},"spNyl","const",[176,673,674],{"class":193}," file ",[176,676,412],{"class":197},[176,678,679],{"class":182}," await",[176,681,646],{"class":193},[176,683,471],{"class":197},[176,685,686],{"class":189},"put",[176,688,194],{"class":193},[176,690,319],{"class":197},[176,692,693],{"class":315},"avatars/user-1.png",[176,695,319],{"class":197},[176,697,698],{"class":197},",",[176,700,701],{"class":193}," imageData)\n",[703,704,705],"tip",{"to":66},"Learn how to upload files with validation and progress tracking.",[152,707,709],{"id":708},"driver-options","Driver options",[157,711,712,713,471],{},"You can set a custom driver by providing a configuration object to ",[161,714,715],{},"blob",[166,717,719],{"className":168,"code":718,"filename":170,"language":171,"meta":172,"style":172},"export default defineNuxtConfig({\n  hub: {\n    blob: {\n      driver: 'fs',\n      dir: '.data/blob'\n    }\n  },\n  // or overwrite only in production\n  $production: {\n    hub: {\n      blob: {\n        driver: 'vercel-blob'\n      }\n    }\n  }\n})\n",[161,720,721,733,741,749,763,775,779,784,789,799,809,819,834,840,845,850],{"__ignoreMap":172},[176,722,723,725,727,729,731],{"class":178,"line":179},[176,724,183],{"class":182},[176,726,186],{"class":182},[176,728,190],{"class":189},[176,730,194],{"class":193},[176,732,198],{"class":197},[176,734,735,737,739],{"class":178,"line":201},[176,736,205],{"class":204},[176,738,208],{"class":197},[176,740,211],{"class":197},[176,742,743,745,747],{"class":178,"line":214},[176,744,217],{"class":204},[176,746,208],{"class":197},[176,748,211],{"class":197},[176,750,751,753,755,757,759,761],{"class":178,"line":226},[176,752,307],{"class":204},[176,754,208],{"class":197},[176,756,312],{"class":197},[176,758,316],{"class":315},[176,760,319],{"class":197},[176,762,322],{"class":197},[176,764,765,767,769,771,773],{"class":178,"line":232},[176,766,327],{"class":204},[176,768,208],{"class":197},[176,770,312],{"class":197},[176,772,252],{"class":315},[176,774,592],{"class":197},[176,776,777],{"class":178,"line":343},[176,778,346],{"class":197},[176,780,781],{"class":178,"line":349},[176,782,783],{"class":197},"  },\n",[176,785,786],{"class":178,"line":354},[176,787,788],{"class":339},"  // or overwrite only in production\n",[176,790,792,795,797],{"class":178,"line":791},9,[176,793,794],{"class":204},"  $production",[176,796,208],{"class":197},[176,798,211],{"class":197},[176,800,802,805,807],{"class":178,"line":801},10,[176,803,804],{"class":204},"    hub",[176,806,208],{"class":197},[176,808,211],{"class":197},[176,810,812,815,817],{"class":178,"line":811},11,[176,813,814],{"class":204},"      blob",[176,816,208],{"class":197},[176,818,211],{"class":197},[176,820,822,825,827,829,832],{"class":178,"line":821},12,[176,823,824],{"class":204},"        driver",[176,826,208],{"class":197},[176,828,312],{"class":197},[176,830,831],{"class":315},"vercel-blob",[176,833,592],{"class":197},[176,835,837],{"class":178,"line":836},13,[176,838,839],{"class":197},"      }\n",[176,841,843],{"class":178,"line":842},14,[176,844,346],{"class":197},[176,846,848],{"class":178,"line":847},15,[176,849,229],{"class":197},[176,851,853,855],{"class":178,"line":852},16,[176,854,235],{"class":197},[176,856,238],{"class":193},[157,858,859],{},"Available drivers:",[255,861,862,941,1097,1177],{"sync":257},[259,863,864],{"icon":261,"label":262},[166,865,867],{"className":168,"code":866,"language":171,"meta":172,"style":172},"export default defineNuxtConfig({\n  hub: {\n    blob: {\n      driver: 'fs',\n      dir: '.data/files' // defaults to '.data/blob'\n    }\n  }\n})\n",[161,868,869,881,889,897,911,927,931,935],{"__ignoreMap":172},[176,870,871,873,875,877,879],{"class":178,"line":179},[176,872,183],{"class":182},[176,874,186],{"class":182},[176,876,190],{"class":189},[176,878,194],{"class":193},[176,880,198],{"class":197},[176,882,883,885,887],{"class":178,"line":201},[176,884,205],{"class":204},[176,886,208],{"class":197},[176,888,211],{"class":197},[176,890,891,893,895],{"class":178,"line":214},[176,892,217],{"class":204},[176,894,208],{"class":197},[176,896,211],{"class":197},[176,898,899,901,903,905,907,909],{"class":178,"line":226},[176,900,307],{"class":204},[176,902,208],{"class":197},[176,904,312],{"class":197},[176,906,316],{"class":315},[176,908,319],{"class":197},[176,910,322],{"class":197},[176,912,913,915,917,919,922,924],{"class":178,"line":232},[176,914,327],{"class":204},[176,916,208],{"class":197},[176,918,312],{"class":197},[176,920,921],{"class":315},".data/files",[176,923,319],{"class":197},[176,925,926],{"class":339}," // defaults to '.data/blob'\n",[176,928,929],{"class":178,"line":343},[176,930,346],{"class":197},[176,932,933],{"class":178,"line":349},[176,934,229],{"class":197},[176,936,937,939],{"class":178,"line":354},[176,938,235],{"class":197},[176,940,238],{"class":193},[259,942,943],{"icon":365,"label":366},[166,944,946],{"className":168,"code":945,"language":171,"meta":172,"style":172},"export default defineNuxtConfig({\n  hub: {\n    blob: {\n      driver: 's3',\n      accessKeyId: 'your-access-key-id', // defaults to S3_ACCESS_KEY_ID\n      secretAccessKey: 'your-secret-access-key', // defaults to S3_SECRET_ACCESS_KEY\n      bucket: 'your-bucket-name', // defaults to S3_BUCKET\n      region: 'your-region', // defaults to S3_REGION or 'auto'\n      endpoint: 'your-endpoint' // optional, defaults to S3_ENDPOINT\n    }\n  }\n})\n",[161,947,948,960,968,976,991,1010,1029,1048,1067,1083,1087,1091],{"__ignoreMap":172},[176,949,950,952,954,956,958],{"class":178,"line":179},[176,951,183],{"class":182},[176,953,186],{"class":182},[176,955,190],{"class":189},[176,957,194],{"class":193},[176,959,198],{"class":197},[176,961,962,964,966],{"class":178,"line":201},[176,963,205],{"class":204},[176,965,208],{"class":197},[176,967,211],{"class":197},[176,969,970,972,974],{"class":178,"line":214},[176,971,217],{"class":204},[176,973,208],{"class":197},[176,975,211],{"class":197},[176,977,978,980,982,984,987,989],{"class":178,"line":226},[176,979,307],{"class":204},[176,981,208],{"class":197},[176,983,312],{"class":197},[176,985,986],{"class":315},"s3",[176,988,319],{"class":197},[176,990,322],{"class":197},[176,992,993,996,998,1000,1003,1005,1007],{"class":178,"line":232},[176,994,995],{"class":204},"      accessKeyId",[176,997,208],{"class":197},[176,999,312],{"class":197},[176,1001,1002],{"class":315},"your-access-key-id",[176,1004,319],{"class":197},[176,1006,698],{"class":197},[176,1008,1009],{"class":339}," // defaults to S3_ACCESS_KEY_ID\n",[176,1011,1012,1015,1017,1019,1022,1024,1026],{"class":178,"line":343},[176,1013,1014],{"class":204},"      secretAccessKey",[176,1016,208],{"class":197},[176,1018,312],{"class":197},[176,1020,1021],{"class":315},"your-secret-access-key",[176,1023,319],{"class":197},[176,1025,698],{"class":197},[176,1027,1028],{"class":339}," // defaults to S3_SECRET_ACCESS_KEY\n",[176,1030,1031,1034,1036,1038,1041,1043,1045],{"class":178,"line":349},[176,1032,1033],{"class":204},"      bucket",[176,1035,208],{"class":197},[176,1037,312],{"class":197},[176,1039,1040],{"class":315},"your-bucket-name",[176,1042,319],{"class":197},[176,1044,698],{"class":197},[176,1046,1047],{"class":339}," // defaults to S3_BUCKET\n",[176,1049,1050,1053,1055,1057,1060,1062,1064],{"class":178,"line":354},[176,1051,1052],{"class":204},"      region",[176,1054,208],{"class":197},[176,1056,312],{"class":197},[176,1058,1059],{"class":315},"your-region",[176,1061,319],{"class":197},[176,1063,698],{"class":197},[176,1065,1066],{"class":339}," // defaults to S3_REGION or 'auto'\n",[176,1068,1069,1072,1074,1076,1078,1080],{"class":178,"line":791},[176,1070,1071],{"class":204},"      endpoint",[176,1073,208],{"class":197},[176,1075,312],{"class":197},[176,1077,455],{"class":315},[176,1079,319],{"class":197},[176,1081,1082],{"class":339}," // optional, defaults to S3_ENDPOINT\n",[176,1084,1085],{"class":178,"line":801},[176,1086,346],{"class":197},[176,1088,1089],{"class":178,"line":811},[176,1090,229],{"class":197},[176,1092,1093,1095],{"class":178,"line":821},[176,1094,235],{"class":197},[176,1096,238],{"class":193},[259,1098,1099],{"icon":461,"label":462},[166,1100,1102],{"className":168,"code":1101,"language":171,"meta":172,"style":172},"export default defineNuxtConfig({\n  hub: {\n    blob: {\n      driver: 'vercel-blob',\n      token: 'your-token' // optional, defaults to BLOB_READ_WRITE_TOKEN env var\n    }\n  }\n})\n",[161,1103,1104,1116,1124,1132,1146,1163,1167,1171],{"__ignoreMap":172},[176,1105,1106,1108,1110,1112,1114],{"class":178,"line":179},[176,1107,183],{"class":182},[176,1109,186],{"class":182},[176,1111,190],{"class":189},[176,1113,194],{"class":193},[176,1115,198],{"class":197},[176,1117,1118,1120,1122],{"class":178,"line":201},[176,1119,205],{"class":204},[176,1121,208],{"class":197},[176,1123,211],{"class":197},[176,1125,1126,1128,1130],{"class":178,"line":214},[176,1127,217],{"class":204},[176,1129,208],{"class":197},[176,1131,211],{"class":197},[176,1133,1134,1136,1138,1140,1142,1144],{"class":178,"line":226},[176,1135,307],{"class":204},[176,1137,208],{"class":197},[176,1139,312],{"class":197},[176,1141,831],{"class":315},[176,1143,319],{"class":197},[176,1145,322],{"class":197},[176,1147,1148,1151,1153,1155,1158,1160],{"class":178,"line":232},[176,1149,1150],{"class":204},"      token",[176,1152,208],{"class":197},[176,1154,312],{"class":197},[176,1156,1157],{"class":315},"your-token",[176,1159,319],{"class":197},[176,1161,1162],{"class":339}," // optional, defaults to BLOB_READ_WRITE_TOKEN env var\n",[176,1164,1165],{"class":178,"line":343},[176,1166,346],{"class":197},[176,1168,1169],{"class":178,"line":349},[176,1170,229],{"class":197},[176,1172,1173,1175],{"class":178,"line":354},[176,1174,235],{"class":197},[176,1176,238],{"class":193},[259,1178,1179],{"icon":520,"label":521},[166,1180,1182],{"className":168,"code":1181,"language":171,"meta":172,"style":172},"export default defineNuxtConfig({\n  hub: {\n    blob: {\n      driver: 'cloudflare-r2',\n      binding: 'BLOB' // optional, defaults to 'BLOB'\n    }\n  }\n})\n",[161,1183,1184,1196,1204,1212,1226,1243,1247,1251],{"__ignoreMap":172},[176,1185,1186,1188,1190,1192,1194],{"class":178,"line":179},[176,1187,183],{"class":182},[176,1189,186],{"class":182},[176,1191,190],{"class":189},[176,1193,194],{"class":193},[176,1195,198],{"class":197},[176,1197,1198,1200,1202],{"class":178,"line":201},[176,1199,205],{"class":204},[176,1201,208],{"class":197},[176,1203,211],{"class":197},[176,1205,1206,1208,1210],{"class":178,"line":214},[176,1207,217],{"class":204},[176,1209,208],{"class":197},[176,1211,211],{"class":197},[176,1213,1214,1216,1218,1220,1222,1224],{"class":178,"line":226},[176,1215,307],{"class":204},[176,1217,208],{"class":197},[176,1219,312],{"class":197},[176,1221,573],{"class":315},[176,1223,319],{"class":197},[176,1225,322],{"class":197},[176,1227,1228,1231,1233,1235,1238,1240],{"class":178,"line":232},[176,1229,1230],{"class":204},"      binding",[176,1232,208],{"class":197},[176,1234,312],{"class":197},[176,1236,1237],{"class":315},"BLOB",[176,1239,319],{"class":197},[176,1241,1242],{"class":339}," // optional, defaults to 'BLOB'\n",[176,1244,1245],{"class":178,"line":343},[176,1246,346],{"class":197},[176,1248,1249],{"class":178,"line":349},[176,1250,229],{"class":197},[176,1252,1253,1255],{"class":178,"line":354},[176,1254,235],{"class":197},[176,1256,238],{"class":193},[144,1258,1260],{"id":1259},"nuxt-image-integration","Nuxt Image Integration",[157,1262,1263,1270],{},[371,1264,1267],{"href":1265,"rel":1266},"https://image.nuxt.com",[375],[161,1268,1269],{},"@nuxt/image"," provides automatic image optimization. You can combine it with blob storage to serve optimized images from your storage.",[148,1272,1273,1277,1301,1313,1317,1327,1330,1535,1544,1548,1554,1737,1784,1788,1791,1867],{"level":150},[152,1274,1276],{"id":1275},"install-nuxtimage","Install @nuxt/image",[166,1278,1281],{"className":399,"code":1279,"filename":1280,"language":402,"meta":172,"style":172},"npx nuxt module add image\n","Terminal",[161,1282,1283],{"__ignoreMap":172},[176,1284,1285,1289,1292,1295,1298],{"class":178,"line":179},[176,1286,1288],{"class":1287},"sBMFI","npx",[176,1290,1291],{"class":315}," nuxt",[176,1293,1294],{"class":315}," module",[176,1296,1297],{"class":315}," add",[176,1299,1300],{"class":315}," image\n",[703,1302,1303,1304,1306,1307,1310,1311,471],{},"This command will install ",[161,1305,1269],{}," and add it to your ",[161,1308,1309],{},"modules"," section of your ",[161,1312,170],{},[152,1314,1316],{"id":1315},"expose-your-blobs-on-a-route","Expose your blobs on a route",[157,1318,1319,1320,1323,1324,208],{},"Create a server route (for example ",[161,1321,1322],{},"/images/**",") that serves blobs using ",[161,1325,1326],{},"blob.serve()",[157,1328,1329],{},"This route should exist in both development and production. In production, providers like Cloudflare and Vercel optimize by generating URLs that wrap this route.",[166,1331,1334],{"className":168,"code":1332,"filename":1333,"language":171,"meta":172,"style":172},"import { blob } from 'hub:blob'\nimport { createError, eventHandler, getRouterParam } from 'h3'\n\nexport default eventHandler(async (event) => {\n  const pathname = getRouterParam(event, 'pathname')\n  if (!pathname) {\n    throw createError({ statusCode: 404, statusMessage: 'Not Found' })\n  }\n\n  return blob.serve(event, pathname)\n})\n","server/routes/images/[...pathname].get.ts",[161,1335,1336,1354,1383,1387,1415,1443,1460,1499,1503,1507,1529],{"__ignoreMap":172},[176,1337,1338,1340,1342,1344,1346,1348,1350,1352],{"class":178,"line":179},[176,1339,640],{"class":182},[176,1341,643],{"class":197},[176,1343,646],{"class":193},[176,1345,649],{"class":197},[176,1347,652],{"class":182},[176,1349,312],{"class":197},[176,1351,657],{"class":315},[176,1353,592],{"class":197},[176,1355,1356,1358,1360,1363,1365,1368,1370,1373,1375,1377,1379,1381],{"class":178,"line":201},[176,1357,640],{"class":182},[176,1359,643],{"class":197},[176,1361,1362],{"class":193}," createError",[176,1364,698],{"class":197},[176,1366,1367],{"class":193}," eventHandler",[176,1369,698],{"class":197},[176,1371,1372],{"class":193}," getRouterParam",[176,1374,649],{"class":197},[176,1376,652],{"class":182},[176,1378,312],{"class":197},[176,1380,152],{"class":315},[176,1382,592],{"class":197},[176,1384,1385],{"class":178,"line":214},[176,1386,665],{"emptyLinePlaceholder":664},[176,1388,1389,1391,1393,1395,1397,1400,1403,1407,1410,1413],{"class":178,"line":226},[176,1390,183],{"class":182},[176,1392,186],{"class":182},[176,1394,1367],{"class":189},[176,1396,194],{"class":193},[176,1398,1399],{"class":670},"async",[176,1401,1402],{"class":197}," (",[176,1404,1406],{"class":1405},"sHdIc","event",[176,1408,1409],{"class":197},")",[176,1411,1412],{"class":670}," =>",[176,1414,211],{"class":197},[176,1416,1417,1420,1423,1426,1428,1430,1432,1434,1436,1439,1441],{"class":178,"line":232},[176,1418,1419],{"class":670},"  const",[176,1421,1422],{"class":193}," pathname",[176,1424,1425],{"class":197}," =",[176,1427,1372],{"class":189},[176,1429,194],{"class":204},[176,1431,1406],{"class":193},[176,1433,698],{"class":197},[176,1435,312],{"class":197},[176,1437,1438],{"class":315},"pathname",[176,1440,319],{"class":197},[176,1442,238],{"class":204},[176,1444,1445,1448,1450,1453,1455,1458],{"class":178,"line":343},[176,1446,1447],{"class":182},"  if",[176,1449,1402],{"class":204},[176,1451,1452],{"class":197},"!",[176,1454,1438],{"class":193},[176,1456,1457],{"class":204},") ",[176,1459,198],{"class":197},[176,1461,1462,1465,1467,1469,1472,1475,1477,1481,1483,1486,1488,1490,1493,1495,1497],{"class":178,"line":349},[176,1463,1464],{"class":182},"    throw",[176,1466,1362],{"class":189},[176,1468,194],{"class":204},[176,1470,1471],{"class":197},"{",[176,1473,1474],{"class":204}," statusCode",[176,1476,208],{"class":197},[176,1478,1480],{"class":1479},"sbssI"," 404",[176,1482,698],{"class":197},[176,1484,1485],{"class":204}," statusMessage",[176,1487,208],{"class":197},[176,1489,312],{"class":197},[176,1491,1492],{"class":315},"Not Found",[176,1494,319],{"class":197},[176,1496,649],{"class":197},[176,1498,238],{"class":204},[176,1500,1501],{"class":178,"line":354},[176,1502,229],{"class":197},[176,1504,1505],{"class":178,"line":791},[176,1506,665],{"emptyLinePlaceholder":664},[176,1508,1509,1512,1514,1516,1519,1521,1523,1525,1527],{"class":178,"line":801},[176,1510,1511],{"class":182},"  return",[176,1513,646],{"class":193},[176,1515,471],{"class":197},[176,1517,1518],{"class":189},"serve",[176,1520,194],{"class":204},[176,1522,1406],{"class":193},[176,1524,698],{"class":197},[176,1526,1422],{"class":193},[176,1528,238],{"class":204},[176,1530,1531,1533],{"class":178,"line":811},[176,1532,235],{"class":197},[176,1534,238],{"class":193},[703,1536,1538,1539,1543],{"to":1537},"/docs/blob/usage#serve-a-blob","Learn more about serving blobs (headers, CSP, etc.) in the ",[1540,1541,1542],"strong",{},"Serve a blob"," section.",[152,1545,1547],{"id":1546},"configure-the-image-provider","Configure the image provider",[157,1549,1550,1551,1553],{},"Configure ",[161,1552,1269],{}," to use the appropriate provider for your hosting platform:",[255,1555,1557,1650],{"sync":1556},"image-provider",[259,1558,1560,1646],{"icon":520,"label":1559},"Cloudflare",[166,1561,1563],{"className":168,"code":1562,"filename":170,"language":171,"meta":172,"style":172},"export default defineNuxtConfig({\n  image: { provider: 'none' },\n  $production: {\n    image: {\n      provider: 'cloudflare'\n    }\n  }\n})\n",[161,1564,1565,1577,1601,1609,1618,1632,1636,1640],{"__ignoreMap":172},[176,1566,1567,1569,1571,1573,1575],{"class":178,"line":179},[176,1568,183],{"class":182},[176,1570,186],{"class":182},[176,1572,190],{"class":189},[176,1574,194],{"class":193},[176,1576,198],{"class":197},[176,1578,1579,1582,1584,1586,1589,1591,1593,1596,1598],{"class":178,"line":201},[176,1580,1581],{"class":204},"  image",[176,1583,208],{"class":197},[176,1585,643],{"class":197},[176,1587,1588],{"class":204}," provider",[176,1590,208],{"class":197},[176,1592,312],{"class":197},[176,1594,1595],{"class":315},"none",[176,1597,319],{"class":197},[176,1599,1600],{"class":197}," },\n",[176,1602,1603,1605,1607],{"class":178,"line":214},[176,1604,794],{"class":204},[176,1606,208],{"class":197},[176,1608,211],{"class":197},[176,1610,1611,1614,1616],{"class":178,"line":226},[176,1612,1613],{"class":204},"    image",[176,1615,208],{"class":197},[176,1617,211],{"class":197},[176,1619,1620,1623,1625,1627,1630],{"class":178,"line":232},[176,1621,1622],{"class":204},"      provider",[176,1624,208],{"class":197},[176,1626,312],{"class":197},[176,1628,1629],{"class":315},"cloudflare",[176,1631,592],{"class":197},[176,1633,1634],{"class":178,"line":343},[176,1635,346],{"class":197},[176,1637,1638],{"class":178,"line":349},[176,1639,229],{"class":197},[176,1641,1642,1644],{"class":178,"line":354},[176,1643,235],{"class":197},[176,1645,238],{"class":193},[608,1647,1649],{"to":1648},"https://image.nuxt.com/providers/cloudflare","See Cloudflare provider docs for requirements and options.",[259,1651,1653,1733],{"icon":461,"label":1652},"Vercel",[166,1654,1656],{"className":168,"code":1655,"filename":170,"language":171,"meta":172,"style":172},"export default defineNuxtConfig({\n  image: { provider: 'none' },\n  $production: {\n    image: {\n      provider: 'vercel'\n    }\n  }\n})\n",[161,1657,1658,1670,1690,1698,1706,1719,1723,1727],{"__ignoreMap":172},[176,1659,1660,1662,1664,1666,1668],{"class":178,"line":179},[176,1661,183],{"class":182},[176,1663,186],{"class":182},[176,1665,190],{"class":189},[176,1667,194],{"class":193},[176,1669,198],{"class":197},[176,1671,1672,1674,1676,1678,1680,1682,1684,1686,1688],{"class":178,"line":201},[176,1673,1581],{"class":204},[176,1675,208],{"class":197},[176,1677,643],{"class":197},[176,1679,1588],{"class":204},[176,1681,208],{"class":197},[176,1683,312],{"class":197},[176,1685,1595],{"class":315},[176,1687,319],{"class":197},[176,1689,1600],{"class":197},[176,1691,1692,1694,1696],{"class":178,"line":214},[176,1693,794],{"class":204},[176,1695,208],{"class":197},[176,1697,211],{"class":197},[176,1699,1700,1702,1704],{"class":178,"line":226},[176,1701,1613],{"class":204},[176,1703,208],{"class":197},[176,1705,211],{"class":197},[176,1707,1708,1710,1712,1714,1717],{"class":178,"line":232},[176,1709,1622],{"class":204},[176,1711,208],{"class":197},[176,1713,312],{"class":197},[176,1715,1716],{"class":315},"vercel",[176,1718,592],{"class":197},[176,1720,1721],{"class":178,"line":343},[176,1722,346],{"class":197},[176,1724,1725],{"class":178,"line":349},[176,1726,229],{"class":197},[176,1728,1729,1731],{"class":178,"line":354},[176,1730,235],{"class":197},[176,1732,238],{"class":193},[608,1734,1736],{"to":1735},"https://image.nuxt.com/providers/vercel","See Vercel provider docs for requirements and options.",[1738,1739,1741,1755],"warning",{"title":1740},"Development Limitation",[157,1742,1743,1744,1747,1748,1751,1752,471],{},"Cloudflare and Vercel providers generate URLs that only exist in production (",[161,1745,1746],{},"/cdn-cgi/image/"," for Cloudflare, ",[161,1749,1750],{},"/_vercel/image"," for Vercel), so enable them only in ",[161,1753,1754],{},"$production",[157,1756,1757,1758,1760,1761,1764,1765,1768,1769,1771,1772,1775,1776,1779,1780,1783],{},"In development, ",[161,1759,1269],{}," defaults to the ",[161,1762,1763],{},"ipx"," provider if you don't configure it. IPX generates ",[161,1766,1767],{},"/_ipx/..."," URLs and tries to read the source from the filesystem, so it won't work with blob routes like ",[161,1770,1322],{}," (you may see ",[161,1773,1774],{},"IPX_FILE_NOT_FOUND"," errors). Use ",[161,1777,1778],{},"provider: 'none'"," in development to keep ",[161,1781,1782],{},"src=\"/images/...\""," working.",[152,1785,1787],{"id":1786},"use-nuxtimg-or-nuxtpicture","Use NuxtImg or NuxtPicture",[157,1789,1790],{},"Use the components to display optimized images from blob storage:",[166,1792,1797],{"className":1793,"code":1794,"filename":1795,"language":1796,"meta":172,"style":172},"language-vue shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u003Ctemplate>\n  \u003CNuxtImg src=\"/images/photo.jpg\" width=\"300\" quality=\"80\" />\n\u003C/template>\n","pages/gallery.vue","vue",[161,1798,1799,1810,1858],{"__ignoreMap":172},[176,1800,1801,1804,1807],{"class":178,"line":179},[176,1802,1803],{"class":197},"\u003C",[176,1805,1806],{"class":204},"template",[176,1808,1809],{"class":197},">\n",[176,1811,1812,1815,1818,1821,1823,1826,1829,1831,1834,1836,1838,1841,1843,1846,1848,1850,1853,1855],{"class":178,"line":201},[176,1813,1814],{"class":197},"  \u003C",[176,1816,1817],{"class":204},"NuxtImg",[176,1819,1820],{"class":670}," src",[176,1822,412],{"class":197},[176,1824,1825],{"class":197},"\"",[176,1827,1828],{"class":315},"/images/photo.jpg",[176,1830,1825],{"class":197},[176,1832,1833],{"class":670}," width",[176,1835,412],{"class":197},[176,1837,1825],{"class":197},[176,1839,1840],{"class":315},"300",[176,1842,1825],{"class":197},[176,1844,1845],{"class":670}," quality",[176,1847,412],{"class":197},[176,1849,1825],{"class":197},[176,1851,1852],{"class":315},"80",[176,1854,1825],{"class":197},[176,1856,1857],{"class":197}," />\n",[176,1859,1860,1863,1865],{"class":178,"line":214},[176,1861,1862],{"class":197},"\u003C/",[176,1864,1806],{"class":204},[176,1866,1809],{"class":197},[157,1868,1869,1870,1873,1874,1877,1878,1881],{},"The ",[161,1871,1872],{},"src"," path combines your route prefix (",[161,1875,1876],{},"/images",") with the blob pathname (",[161,1879,1880],{},"photo.jpg",").",[1883,1884,1885],"style",{},"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 .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}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 .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}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 .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}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 .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}",{"title":172,"searchDepth":201,"depth":201,"links":1887},[1888,1894],{"id":146,"depth":201,"text":11,"children":1889},[1890,1891,1892,1893],{"id":154,"depth":214,"text":155},{"id":241,"depth":214,"text":242},{"id":622,"depth":214,"text":623},{"id":708,"depth":214,"text":709},{"id":1259,"depth":201,"text":1260,"children":1895},[1896,1897,1898,1899],{"id":1275,"depth":214,"text":1276},{"id":1315,"depth":214,"text":1316},{"id":1546,"depth":214,"text":1547},{"id":1786,"depth":214,"text":1787},"Setup Blob Storage in your Nuxt application to store assets like images, videos, documents. Compatible with AWS S3, Cloudflare R2, Vercel Blob and more.","md",null,{},{"title":40},{"title":139,"description":1900},"fpGfugOZi-2IMvAR6Ta2ShXCuoUeD3puTJmx47LMGis",[1908,1910],{"title":54,"path":55,"stem":56,"description":1909,"children":-1},"Manage your Nuxt SQL database with the `npx nuxt db` CLI, including generating migrations, applying them, running SQL queries, and marking migrations as applied.",{"title":65,"path":66,"stem":67,"description":1911,"children":-1},"Learn how to upload files in your Nuxt application using validation, simple uploads, and multipart uploads for large files.",1774893097709]