[{"data":1,"prerenderedAt":1489},["ShallowReactive",2],{"navigation_docs":3,"-medias":44,"-medias-surround":1484},[4,9,14,19,24,29,34,39],{"title":5,"path":6,"stem":7,"icon":8},"Introduction","\u002Fintroduction","1.introduction","i-lucide-monitor",{"title":10,"path":11,"stem":12,"icon":13},"Setup","\u002Fsetup","2.setup","i-lucide-play",{"title":15,"path":16,"stem":17,"icon":18},"Git Providers","\u002Fgit-providers","3.git-providers","i-lucide-git-branch",{"title":20,"path":21,"stem":22,"icon":23},"Auth Providers","\u002Fauth-providers","4.auth-providers","i-lucide-shield-check",{"title":25,"path":26,"stem":27,"icon":28},"Content Editors","\u002Fcontent","5.content","i-lucide-pen-tool",{"title":30,"path":31,"stem":32,"icon":33},"Media Library","\u002Fmedias","6.medias","i-lucide-image",{"title":35,"path":36,"stem":37,"icon":38},"AI Features","\u002Fai","7.ai","i-lucide-sparkles",{"title":40,"path":41,"stem":42,"icon":43},"Advanced","\u002Fadvanced","9.advanced","i-lucide-settings",{"id":45,"title":46,"body":47,"description":1475,"extension":1476,"links":1477,"meta":1478,"navigation":1479,"path":31,"seo":1480,"stem":32,"__hash__":1483},"docs\u002F6.medias.md","Manage and integrate Medias in Nuxt Content Studio CMS",{"type":48,"value":49,"toc":1459},"minimark",[50,55,69,75,78,82,85,133,137,140,160,164,247,255,261,264,268,281,289,294,805,810,814,825,932,936,939,942,1147,1149,1455],[51,52,54],"h2",{"id":53},"browse","Browse",[56,57,58,59,63,64,68],"p",{},"All medias located in the ",[60,61,62],"code",{},"\u002Fpublic"," directory are available in the ",[65,66,67],"strong",{},"Media"," tab of the Studio interface.",[56,70,71,72,74],{},"It's an intuitive interface for non-technical users to manage their ",[60,73,62],{}," directory or external storage if set.",[56,76,77],{},"Users can easily browse folders, upload new media at any level, and drag and drop files, making media organization straightforward.",[51,79,81],{"id":80},"editor-integration","Editor integration",[56,83,84],{},"The TipTap visual editor provides seamless media integration:",[86,87,88,99,113,127],"ul",{},[89,90,91,94,95],"li",{},[65,92,93],{},"Drag and drop"," - Simply drag and drop images directly into the editor. An upload modal will open to let you choose the destination folder ",[96,97,98],"badge",{},"Coming Soon",[89,100,101,104,105,108,109,112],{},[65,102,103],{},"Slash commands"," - Type ",[60,106,107],{},"\u002F"," and search for ",[60,110,111],{},"Image"," to quickly insert a media. A modal will open to let you choose the media from your library",[89,114,115,118,119,126],{},[65,116,117],{},"Alt text support"," - From the media modal, you can set the ",[120,121,125],"a",{"href":122,"rel":123},"https:\u002F\u002Fwww.w3schools.com\u002Ftags\u002Fatt_img_alt.asp",[124],"nofollow","alt attribute"," for SEO and accessibility",[89,128,129,132],{},[65,130,131],{},"Attributes support"," - From the media modal, you can set additional attributes like width, height, and custom properties for advanced use cases.",[51,134,136],{"id":135},"supported-file-types","Supported file types",[56,138,139],{},"The media library supports the following file types:",[86,141,142,148,154],{},[89,143,144,147],{},[65,145,146],{},"Images",": PNG, JPG\u002FJPEG, SVG, WebP, AVIF, ICO, GIF",[89,149,150,153],{},[65,151,152],{},"Videos",": MP4, MOV, AVI, MKV, WebM, OGG",[89,155,156,159],{},[65,157,158],{},"Audio",": MP3, WAV, AAC, M4A",[51,161,163],{"id":162},"storage-comparison","Storage Comparison",[165,166,167,183],"table",{},[168,169,170],"thead",{},[171,172,173,177,180],"tr",{},[174,175,176],"th",{},"Feature",[174,178,179],{},"Default storage",[174,181,182],{},"External storage",[184,185,186,201,214,225,236],"tbody",{},[171,187,188,191,194],{},[189,190,10],"td",{},[189,192,193],{},"Zero configuration",[189,195,196,197,200],{},"Requires ",[60,198,199],{},"@nuxthub\u002Fcore"," with blob storage enabled",[171,202,203,206,211],{},[189,204,205],{},"Storage location",[189,207,208,210],{},[60,209,62],{}," directory",[189,212,213],{},"Cloudflare R2, Vercel Blob, or S3-compatible",[171,215,216,219,222],{},[189,217,218],{},"Git commits",[189,220,221],{},"Files committed to Git",[189,223,224],{},"Only URLs referenced",[171,226,227,230,233],{},[189,228,229],{},"Repository size",[189,231,232],{},"Grows with media",[189,234,235],{},"Stays small",[171,237,238,241,244],{},[189,239,240],{},"Best for",[189,242,243],{},"Small projects",[189,245,246],{},"Large media libraries",[51,248,250,251,254],{"id":249},"default-storage-public-folder","Default storage (",[60,252,253],{},"public"," folder)",[56,256,257,258,260],{},"By default, media files are stored in your ",[60,259,62],{}," directory and committed to Git when you publish. This works great for most projects and requires zero configuration.",[56,262,263],{},"Studio tracks all changes to the public folder as drafts in the browser until you publish. A service worker intercepts media requests to serve draft versions instantly, so you see your changes in the preview before they are committed.",[51,265,267],{"id":266},"external-storage","External Storage",[56,269,270,271,274,275,280],{},"For larger projects or teams with many media files, you can configure ",[65,272,273],{},"external storage"," to upload files directly to cloud storage. Studio uses ",[120,276,279],{"href":277,"rel":278},"https:\u002F\u002Fhub.nuxt.com\u002Fdocs\u002Fblob",[124],"NuxtHub Blob Storage"," which supports Vercel Blob, AWS S3 and other S3-compatible providers.",[282,283,284,285,288],"note",{},"Files uploaded to external storage are ",[65,286,287],{},"not committed to Git",". They are stored permanently in your cloud storage bucket and accessed via their public URL.",[290,291,293],"h3",{"id":292},"configuration","Configuration",[295,296,298,303,335,339,500,517,521,528],"steps",{"level":297},"4",[299,300,302],"h4",{"id":301},"install-the-nuxthub-module","Install the NuxtHub module",[304,305,311],"pre",{"className":306,"code":307,"filename":308,"language":309,"meta":310,"style":310},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","npx nuxi module add hub\n","Terminal","bash","",[60,312,313],{"__ignoreMap":310},[314,315,318,322,326,329,332],"span",{"class":316,"line":317},"line",1,[314,319,321],{"class":320},"sBMFI","npx",[314,323,325],{"class":324},"sfazB"," nuxi",[314,327,328],{"class":324}," module",[314,330,331],{"class":324}," add",[314,333,334],{"class":324}," hub\n",[299,336,338],{"id":337},"enable-blob-storage-and-studio-external-media","Enable blob storage and Studio external media:",[304,340,345],{"className":341,"code":342,"filename":343,"language":344,"meta":310,"style":310},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","export default defineNuxtConfig({\n  modules: ['@nuxthub\u002Fcore', 'nuxt-studio'],\n\n  hub: {\n    blob: true,\n  },\n\n  studio: {\n    media: {\n      external: true,\n    },\n  },\n})\n","nuxt.config.ts","ts",[60,346,347,368,405,412,423,437,443,448,458,468,480,486,491],{"__ignoreMap":310},[314,348,349,353,356,360,364],{"class":316,"line":317},[314,350,352],{"class":351},"s7zQu","export",[314,354,355],{"class":351}," default",[314,357,359],{"class":358},"s2Zo4"," defineNuxtConfig",[314,361,363],{"class":362},"sTEyZ","(",[314,365,367],{"class":366},"sMK4o","{\n",[314,369,371,375,378,381,384,386,388,391,394,397,399,402],{"class":316,"line":370},2,[314,372,374],{"class":373},"swJcz","  modules",[314,376,377],{"class":366},":",[314,379,380],{"class":362}," [",[314,382,383],{"class":366},"'",[314,385,199],{"class":324},[314,387,383],{"class":366},[314,389,390],{"class":366},",",[314,392,393],{"class":366}," '",[314,395,396],{"class":324},"nuxt-studio",[314,398,383],{"class":366},[314,400,401],{"class":362},"]",[314,403,404],{"class":366},",\n",[314,406,408],{"class":316,"line":407},3,[314,409,411],{"emptyLinePlaceholder":410},true,"\n",[314,413,415,418,420],{"class":316,"line":414},4,[314,416,417],{"class":373},"  hub",[314,419,377],{"class":366},[314,421,422],{"class":366}," {\n",[314,424,426,429,431,435],{"class":316,"line":425},5,[314,427,428],{"class":373},"    blob",[314,430,377],{"class":366},[314,432,434],{"class":433},"sfNiH"," true",[314,436,404],{"class":366},[314,438,440],{"class":316,"line":439},6,[314,441,442],{"class":366},"  },\n",[314,444,446],{"class":316,"line":445},7,[314,447,411],{"emptyLinePlaceholder":410},[314,449,451,454,456],{"class":316,"line":450},8,[314,452,453],{"class":373},"  studio",[314,455,377],{"class":366},[314,457,422],{"class":366},[314,459,461,464,466],{"class":316,"line":460},9,[314,462,463],{"class":373},"    media",[314,465,377],{"class":366},[314,467,422],{"class":366},[314,469,471,474,476,478],{"class":316,"line":470},10,[314,472,473],{"class":373},"      external",[314,475,377],{"class":366},[314,477,434],{"class":433},[314,479,404],{"class":366},[314,481,483],{"class":316,"line":482},11,[314,484,485],{"class":366},"    },\n",[314,487,489],{"class":316,"line":488},12,[314,490,442],{"class":366},[314,492,494,497],{"class":316,"line":493},13,[314,495,496],{"class":366},"}",[314,498,499],{"class":362},")\n",[501,502,503,505,506,509,510,512,513,516],"warning",{},[60,504,199],{}," must be listed ",[65,507,508],{},"before"," ",[60,511,396],{}," in the ",[60,514,515],{},"modules"," array.",[299,518,520],{"id":519},"set-a-driver","Set a driver",[282,522,523,524,527],{},"By default, if NuxtHub cannot detect a driver, files are stored locally in the ",[60,525,526],{},".data\u002Fblob"," directory.",[529,530,532,639,707,802],"tabs",{"sync":531},"blob-provider",[533,534,537,546,557,560,565],"tabs-item",{"icon":535,"label":536},"i-simple-icons-amazons3","S3 compatible storage",[56,538,539,540,545],{},"To configure ",[120,541,544],{"href":542,"rel":543},"https:\u002F\u002Faws.amazon.com\u002Fs3\u002F",[124],"Amazon S3"," or any other S3-compatible storage:",[56,547,548,509,551,509,554],{},[65,549,550],{},"Install the",[60,552,553],{},"aws4fetch",[65,555,556],{},"package:",[558,559],"pm-install",{"name":553},[56,561,562],{},[65,563,564],{},"Set the following environment variables:",[304,566,569],{"className":306,"code":567,"filename":568,"language":309,"meta":310,"style":310},"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 # (optional)\nNUXT_PUBLIC_STUDIO_MEDIA_PUBLIC_URL=your-public-url # (optional, mandatory for Cloudflare R2 provider)\nS3_ENDPOINT=your-endpoint\n",".env",[60,570,571,582,592,602,616,629],{"__ignoreMap":310},[314,572,573,576,579],{"class":316,"line":317},[314,574,575],{"class":362},"S3_ACCESS_KEY_ID",[314,577,578],{"class":366},"=",[314,580,581],{"class":324},"your-access-key-id\n",[314,583,584,587,589],{"class":316,"line":370},[314,585,586],{"class":362},"S3_SECRET_ACCESS_KEY",[314,588,578],{"class":366},[314,590,591],{"class":324},"your-secret-access-key\n",[314,593,594,597,599],{"class":316,"line":407},[314,595,596],{"class":362},"S3_BUCKET",[314,598,578],{"class":366},[314,600,601],{"class":324},"your-bucket-name\n",[314,603,604,607,609,612],{"class":316,"line":414},[314,605,606],{"class":362},"S3_REGION",[314,608,578],{"class":366},[314,610,611],{"class":324},"your-region",[314,613,615],{"class":614},"sHwdD"," # (optional)\n",[314,617,618,621,623,626],{"class":316,"line":425},[314,619,620],{"class":362},"NUXT_PUBLIC_STUDIO_MEDIA_PUBLIC_URL",[314,622,578],{"class":366},[314,624,625],{"class":324},"your-public-url",[314,627,628],{"class":614}," # (optional, mandatory for Cloudflare R2 provider)\n",[314,630,631,634,636],{"class":316,"line":439},[314,632,633],{"class":362},"S3_ENDPOINT",[314,635,578],{"class":366},[314,637,638],{"class":324},"your-endpoint\n",[533,640,643,650,659,661,666,693],{"icon":641,"label":642},"i-simple-icons-vercel","Vercel Blob",[56,644,539,645,377],{},[120,646,649],{"href":647,"rel":648},"https:\u002F\u002Fvercel.com\u002Fdocs\u002Fstorage\u002Fvercel-blob",[124],"Vercel Blob Storage",[56,651,652,509,654,509,657],{},[65,653,550],{},[60,655,656],{},"@vercel\u002Fblob",[65,658,556],{},[558,660],{"name":656},[56,662,663],{},[65,664,665],{},"Then follow these steps according to the environment you are using:",[667,668,669,682],"ol",{},[89,670,671,672,677,678,681],{},"Assign a Vercel Blob Store to your project from the ",[120,673,676],{"href":674,"rel":675},"https:\u002F\u002Fvercel.com\u002F",[124],"Vercel dashboard"," -> Project -> Storage ",[65,679,680],{},"in production",".",[89,683,684,685,688,689,692],{},"Use ",[60,686,687],{},"VERCEL_BLOB_READ_WRITE_TOKEN"," in ",[65,690,691],{},"local development"," to authenticate.",[304,694,696],{"className":306,"code":695,"filename":568,"language":309,"meta":310,"style":310},"VERCEL_BLOB_READ_WRITE_TOKEN=your-token\n",[60,697,698],{"__ignoreMap":310},[314,699,700,702,704],{"class":316,"line":317},[314,701,687],{"class":362},[314,703,578],{"class":366},[314,705,706],{"class":324},"your-token\n",[533,708,711,719,799],{"icon":709,"label":710},"i-simple-icons-cloudflare","Cloudflare R2",[56,712,713,714,718],{},"When deploying to Cloudflare, configure ",[120,715,710],{"href":716,"rel":717},"https:\u002F\u002Fdevelopers.cloudflare.com\u002Fr2\u002F",[124]," by providing the bucket name. NuxtHub auto-generates the wrangler bindings at build time.",[304,720,722],{"className":341,"code":721,"filename":343,"language":344,"meta":310,"style":310},"export default defineNuxtConfig({\n  hub: {\n    blob: {\n      driver: 'cloudflare-r2',\n      bucketName: '\u003Cbucket-name>'\n    }\n  }\n})\n",[60,723,724,736,744,752,768,783,788,793],{"__ignoreMap":310},[314,725,726,728,730,732,734],{"class":316,"line":317},[314,727,352],{"class":351},[314,729,355],{"class":351},[314,731,359],{"class":358},[314,733,363],{"class":362},[314,735,367],{"class":366},[314,737,738,740,742],{"class":316,"line":370},[314,739,417],{"class":373},[314,741,377],{"class":366},[314,743,422],{"class":366},[314,745,746,748,750],{"class":316,"line":407},[314,747,428],{"class":373},[314,749,377],{"class":366},[314,751,422],{"class":366},[314,753,754,757,759,761,764,766],{"class":316,"line":414},[314,755,756],{"class":373},"      driver",[314,758,377],{"class":366},[314,760,393],{"class":366},[314,762,763],{"class":324},"cloudflare-r2",[314,765,383],{"class":366},[314,767,404],{"class":366},[314,769,770,773,775,777,780],{"class":316,"line":425},[314,771,772],{"class":373},"      bucketName",[314,774,377],{"class":366},[314,776,393],{"class":366},[314,778,779],{"class":324},"\u003Cbucket-name>",[314,781,782],{"class":366},"'\n",[314,784,785],{"class":316,"line":439},[314,786,787],{"class":366},"    }\n",[314,789,790],{"class":316,"line":445},[314,791,792],{"class":366},"  }\n",[314,794,795,797],{"class":316,"line":450},[314,796,496],{"class":366},[314,798,499],{"class":362},[282,800,801],{},"To use Cloudflare R2 without hosting on Cloudflare Workers, use S3 compatible storage with the appropriate environment variables.",[56,803,804],{},":::",[806,807,809],"tip",{"to":808},"https:\u002F\u002Fhub.nuxt.com\u002Fdocs\u002Fstorage\u002Fblob","See the NuxtHub blob documentation for detailed provider setup and environment variable configuration.",[290,811,813],{"id":812},"options","Options",[282,815,816,817,820,821,824],{},"Studio only manages files stored under the configured prefix in your bucket. Files uploaded through the Studio interface are stored as ",[60,818,819],{},"\u003Cprefix>\u002F\u003Cpath>"," (default: ",[60,822,823],{},"studio\u002F\u003Cpath>",") and only those files are listed, browsed, or deleted from within Studio. Any other files already in your bucket are left untouched.",[165,826,827,843],{},[168,828,829],{},[171,830,831,834,837,840],{},[174,832,833],{},"Option",[174,835,836],{},"Type",[174,838,839],{},"Default",[174,841,842],{},"Description",[184,844,845,865,886,910],{},[171,846,847,852,857,862],{},[189,848,849],{},[60,850,851],{},"external",[189,853,854],{},[60,855,856],{},"boolean",[189,858,859],{},[60,860,861],{},"false",[189,863,864],{},"Enable external storage via NuxtHub blob",[171,866,867,872,877,883],{},[189,868,869],{},[60,870,871],{},"maxFileSize",[189,873,874],{},[60,875,876],{},"number",[189,878,879,882],{},[60,880,881],{},"10485760"," (10 MB)",[189,884,885],{},"Maximum upload size in bytes, enforced server-side",[171,887,888,893,898,903],{},[189,889,890],{},[60,891,892],{},"allowedTypes",[189,894,895],{},[60,896,897],{},"string[]",[189,899,900],{},[60,901,902],{},"['image\u002F*', 'video\u002F*', 'audio\u002F*']",[189,904,905,906,909],{},"Allowed MIME types. Wildcards supported (e.g. ",[60,907,908],{},"image\u002F*",")",[171,911,912,917,922,927],{},[189,913,914],{},[60,915,916],{},"prefix",[189,918,919],{},[60,920,921],{},"string",[189,923,924],{},[60,925,926],{},"'studio'",[189,928,929,930],{},"Bucket key prefix for uploaded files. Files are stored as ",[60,931,819],{},[51,933,935],{"id":934},"examples","Examples",[56,937,938],{},"List of examples for different storage providers.",[290,940,642],{"id":941},"vercel-blob",[295,943,944,948,981,985,999,1003,1012,1016,1019,1035],{"level":297},[299,945,947],{"id":946},"create-a-blob-store","Create a Blob store",[667,949,950,963,974],{},[89,951,952,953,958,959,962],{},"Go to your ",[120,954,957],{"href":955,"rel":956},"https:\u002F\u002Fvercel.com\u002Fdashboard",[124],"Vercel Dashboard"," and open the ",[65,960,961],{},"Storage"," tab",[89,964,965,966,969,970,973],{},"Click ",[65,967,968],{},"Create Database",", select ",[65,971,972],{},"Blob",", and give it a name",[89,975,976,977,980],{},"Copy the ",[60,978,979],{},"BLOB_READ_WRITE_TOKEN"," value shown after creation",[299,982,984],{"id":983},"set-environment-variables","Set environment variables",[304,986,988],{"className":306,"code":987,"filename":568,"language":309,"meta":310,"style":310},"BLOB_READ_WRITE_TOKEN=vercel_blob_rw_************\n",[60,989,990],{"__ignoreMap":310},[314,991,992,994,996],{"class":316,"line":317},[314,993,979],{"class":362},[314,995,578],{"class":366},[314,997,998],{"class":324},"vercel_blob_rw_************\n",[299,1000,1002],{"id":1001},"link-to-your-project-in-production","Link to your project in production",[56,1004,1005,1006,1008,1009,1011],{},"From your Vercel project, go to ",[65,1007,961],{}," and connect the blob store you just created. Vercel will automatically inject the ",[60,1010,979],{}," environment variable at runtime.",[299,1013,1015],{"id":1014},"enable-and-configure-nuxthub","Enable and configure NuxtHub",[56,1017,1018],{},"Install the NuxtHub module and enable blob storage:",[304,1020,1021],{"className":306,"code":307,"filename":308,"language":309,"meta":310,"style":310},[60,1022,1023],{"__ignoreMap":310},[314,1024,1025,1027,1029,1031,1033],{"class":316,"line":317},[314,1026,321],{"class":320},[314,1028,325],{"class":324},[314,1030,328],{"class":324},[314,1032,331],{"class":324},[314,1034,334],{"class":324},[304,1036,1037],{"className":341,"code":342,"filename":343,"language":344,"meta":310,"style":310},[60,1038,1039,1051,1077,1081,1089,1099,1103,1107,1115,1123,1133,1137,1141],{"__ignoreMap":310},[314,1040,1041,1043,1045,1047,1049],{"class":316,"line":317},[314,1042,352],{"class":351},[314,1044,355],{"class":351},[314,1046,359],{"class":358},[314,1048,363],{"class":362},[314,1050,367],{"class":366},[314,1052,1053,1055,1057,1059,1061,1063,1065,1067,1069,1071,1073,1075],{"class":316,"line":370},[314,1054,374],{"class":373},[314,1056,377],{"class":366},[314,1058,380],{"class":362},[314,1060,383],{"class":366},[314,1062,199],{"class":324},[314,1064,383],{"class":366},[314,1066,390],{"class":366},[314,1068,393],{"class":366},[314,1070,396],{"class":324},[314,1072,383],{"class":366},[314,1074,401],{"class":362},[314,1076,404],{"class":366},[314,1078,1079],{"class":316,"line":407},[314,1080,411],{"emptyLinePlaceholder":410},[314,1082,1083,1085,1087],{"class":316,"line":414},[314,1084,417],{"class":373},[314,1086,377],{"class":366},[314,1088,422],{"class":366},[314,1090,1091,1093,1095,1097],{"class":316,"line":425},[314,1092,428],{"class":373},[314,1094,377],{"class":366},[314,1096,434],{"class":433},[314,1098,404],{"class":366},[314,1100,1101],{"class":316,"line":439},[314,1102,442],{"class":366},[314,1104,1105],{"class":316,"line":445},[314,1106,411],{"emptyLinePlaceholder":410},[314,1108,1109,1111,1113],{"class":316,"line":450},[314,1110,453],{"class":373},[314,1112,377],{"class":366},[314,1114,422],{"class":366},[314,1116,1117,1119,1121],{"class":316,"line":460},[314,1118,463],{"class":373},[314,1120,377],{"class":366},[314,1122,422],{"class":366},[314,1124,1125,1127,1129,1131],{"class":316,"line":470},[314,1126,473],{"class":373},[314,1128,377],{"class":366},[314,1130,434],{"class":433},[314,1132,404],{"class":366},[314,1134,1135],{"class":316,"line":482},[314,1136,485],{"class":366},[314,1138,1139],{"class":316,"line":488},[314,1140,442],{"class":366},[314,1142,1143,1145],{"class":316,"line":493},[314,1144,496],{"class":366},[314,1146,499],{"class":362},[290,1148,710],{"id":763},[295,1150,1151,1155,1193,1197,1231,1234,1241,1322,1325,1327,1343],{"level":297},[299,1152,1154],{"id":1153},"create-an-r2-bucket","Create an R2 bucket",[667,1156,1157,1169,1178],{},[89,1158,1159,1160,1165,1166],{},"Go to ",[120,1161,1164],{"href":1162,"rel":1163},"https:\u002F\u002Fdash.cloudflare.com",[124],"Cloudflare Dashboard"," and navigate to ",[65,1167,1168],{},"R2 Object Storage",[89,1170,965,1171,1174,1175,909],{},[65,1172,1173],{},"Create bucket"," and give it a name (e.g., ",[60,1176,1177],{},"my-studio-media",[89,1179,1180,1181,1184,1185,1188,1189,1192],{},"In your bucket ",[65,1182,1183],{},"Settings",", enable ",[65,1186,1187],{},"Public access"," (via an ",[60,1190,1191],{},"r2.dev"," subdomain or a custom domain) so uploaded files are publicly accessible",[299,1194,1196],{"id":1195},"create-an-r2-api-token","Create an R2 API token",[667,1198,1199,1211,1221],{},[89,1200,1201,1202,1207,1208],{},"From the ",[120,1203,1206],{"href":1204,"rel":1205},"https:\u002F\u002Fdash.cloudflare.com\u002F?to=\u002F:account\u002Fr2\u002Foverview",[124],"R2 overview"," page, click ",[65,1209,1210],{},"Manage R2 API Tokens",[89,1212,1213,1216,1217,1220],{},[65,1214,1215],{},"Create API token"," and set the permission to ",[65,1218,1219],{},"Object Read & Write"," — this allows Studio to read, write, and list objects",[89,1222,1223,1224,1227,1228,1230],{},"Under ",[65,1225,1226],{},"Specify bucket(s)",", select your bucket (e.g., ",[60,1229,1177],{},") to restrict the token's scope",[299,1232,984],{"id":1233},"set-environment-variables-1",[56,1235,1236,1237,1240],{},"Your ",[65,1238,1239],{},"Account ID"," is visible in the right sidebar of the R2 overview page or in your Cloudflare account URL.",[304,1242,1244],{"className":306,"code":1243,"filename":568,"language":309,"meta":310,"style":310},"S3_ACCESS_KEY_ID=\u003Cr2_access_key_id>\nS3_SECRET_ACCESS_KEY=\u003Cr2_secret_access_key>\nS3_ENDPOINT=https:\u002F\u002F\u003Caccount_id>.r2.cloudflarestorage.com\nS3_BUCKET=my-studio-media\nNUXT_PUBLIC_STUDIO_MEDIA_PUBLIC_URL=https:\u002F\u002Fpub-\u003Chash>.r2.dev   # or your custom domain\n",[60,1245,1246,1259,1270,1291,1300],{"__ignoreMap":310},[314,1247,1248,1250,1253,1256],{"class":316,"line":317},[314,1249,575],{"class":362},[314,1251,1252],{"class":366},"=\u003C",[314,1254,1255],{"class":324},"r2_access_key_id",[314,1257,1258],{"class":366},">\n",[314,1260,1261,1263,1265,1268],{"class":316,"line":370},[314,1262,586],{"class":362},[314,1264,1252],{"class":366},[314,1266,1267],{"class":324},"r2_secret_access_key",[314,1269,1258],{"class":366},[314,1271,1272,1274,1276,1279,1282,1285,1288],{"class":316,"line":407},[314,1273,633],{"class":362},[314,1275,578],{"class":366},[314,1277,1278],{"class":324},"https:\u002F\u002F",[314,1280,1281],{"class":366},"\u003C",[314,1283,1284],{"class":324},"account_id",[314,1286,1287],{"class":366},">",[314,1289,1290],{"class":324},".r2.cloudflarestorage.com\n",[314,1292,1293,1295,1297],{"class":316,"line":414},[314,1294,596],{"class":362},[314,1296,578],{"class":366},[314,1298,1299],{"class":324},"my-studio-media\n",[314,1301,1302,1304,1306,1309,1311,1314,1316,1319],{"class":316,"line":425},[314,1303,620],{"class":362},[314,1305,578],{"class":366},[314,1307,1308],{"class":324},"https:\u002F\u002Fpub-",[314,1310,1281],{"class":366},[314,1312,1313],{"class":324},"hash",[314,1315,1287],{"class":366},[314,1317,1318],{"class":324},".r2.dev",[314,1320,1321],{"class":614},"   # or your custom domain\n",[299,1323,1015],{"id":1324},"enable-and-configure-nuxthub-1",[56,1326,1018],{},[304,1328,1329],{"className":306,"code":307,"filename":308,"language":309,"meta":310,"style":310},[60,1330,1331],{"__ignoreMap":310},[314,1332,1333,1335,1337,1339,1341],{"class":316,"line":317},[314,1334,321],{"class":320},[314,1336,325],{"class":324},[314,1338,328],{"class":324},[314,1340,331],{"class":324},[314,1342,334],{"class":324},[304,1344,1345],{"className":341,"code":342,"filename":343,"language":344,"meta":310,"style":310},[60,1346,1347,1359,1385,1389,1397,1407,1411,1415,1423,1431,1441,1445,1449],{"__ignoreMap":310},[314,1348,1349,1351,1353,1355,1357],{"class":316,"line":317},[314,1350,352],{"class":351},[314,1352,355],{"class":351},[314,1354,359],{"class":358},[314,1356,363],{"class":362},[314,1358,367],{"class":366},[314,1360,1361,1363,1365,1367,1369,1371,1373,1375,1377,1379,1381,1383],{"class":316,"line":370},[314,1362,374],{"class":373},[314,1364,377],{"class":366},[314,1366,380],{"class":362},[314,1368,383],{"class":366},[314,1370,199],{"class":324},[314,1372,383],{"class":366},[314,1374,390],{"class":366},[314,1376,393],{"class":366},[314,1378,396],{"class":324},[314,1380,383],{"class":366},[314,1382,401],{"class":362},[314,1384,404],{"class":366},[314,1386,1387],{"class":316,"line":407},[314,1388,411],{"emptyLinePlaceholder":410},[314,1390,1391,1393,1395],{"class":316,"line":414},[314,1392,417],{"class":373},[314,1394,377],{"class":366},[314,1396,422],{"class":366},[314,1398,1399,1401,1403,1405],{"class":316,"line":425},[314,1400,428],{"class":373},[314,1402,377],{"class":366},[314,1404,434],{"class":433},[314,1406,404],{"class":366},[314,1408,1409],{"class":316,"line":439},[314,1410,442],{"class":366},[314,1412,1413],{"class":316,"line":445},[314,1414,411],{"emptyLinePlaceholder":410},[314,1416,1417,1419,1421],{"class":316,"line":450},[314,1418,453],{"class":373},[314,1420,377],{"class":366},[314,1422,422],{"class":366},[314,1424,1425,1427,1429],{"class":316,"line":460},[314,1426,463],{"class":373},[314,1428,377],{"class":366},[314,1430,422],{"class":366},[314,1432,1433,1435,1437,1439],{"class":316,"line":470},[314,1434,473],{"class":373},[314,1436,377],{"class":366},[314,1438,434],{"class":433},[314,1440,404],{"class":366},[314,1442,1443],{"class":316,"line":482},[314,1444,485],{"class":366},[314,1446,1447],{"class":316,"line":488},[314,1448,442],{"class":366},[314,1450,1451,1453],{"class":316,"line":493},[314,1452,496],{"class":366},[314,1454,499],{"class":362},[1456,1457,1458],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}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 .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 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}",{"title":310,"searchDepth":370,"depth":370,"links":1460},[1461,1462,1463,1464,1465,1467,1471],{"id":53,"depth":370,"text":54},{"id":80,"depth":370,"text":81},{"id":135,"depth":370,"text":136},{"id":162,"depth":370,"text":163},{"id":249,"depth":370,"text":1466},"Default storage (public folder)",{"id":266,"depth":370,"text":267,"children":1468},[1469,1470],{"id":292,"depth":407,"text":293},{"id":812,"depth":407,"text":813},{"id":934,"depth":370,"text":935,"children":1472},[1473,1474],{"id":941,"depth":407,"text":642},{"id":763,"depth":407,"text":710},"Explore how to browse and manage media files, including external storage with NuxtHub blob storage, and integrate them into your projects.","md",null,{},{"title":30,"icon":33},{"title":1481,"description":1482},"Nuxt Studio Media Library and External Storage","Learn how to manage media files in Nuxt Studio, including external storage integration with NuxtHub blob storage and Cloudflare R2.","iYgV8zP3iCXqw1QnNwD63_w0RYY1ZxCibgoQcb03kd0",[1485,1487],{"title":25,"path":26,"stem":27,"description":1486,"icon":28,"children":-1},"Discover and select your favorite way to manage your content between the visual or the code editor.",{"title":35,"path":36,"stem":37,"description":1488,"icon":38,"children":-1},"Learn how to enable and use AI-powered features in Nuxt Studio for intelligent content completion, transformation, and style guidance.",1782939002707]