[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"navigation_en":3,"/docs/features/storage-data":144},[4,16,91,117,127],{"title":5,"path":6,"stem":7,"children":8,"icon":15},"Getting Started","/docs/get-started","docs/1.get-started/1.index",[9,11],{"title":10,"path":6,"stem":7},"Introduction",{"title":12,"path":13,"stem":14},"Setup","/docs/get-started/setup","docs/1.get-started/2.setup","mage:fast-forward-fill",{"title":17,"icon":18,"path":19,"stem":20,"children":21,"page":90},"Features","ic:baseline-cable","/docs/features","docs/2.features",[22,26,30,34,38,42,46,50,54,58,62,66,70,74,78,82,86],{"title":23,"path":24,"stem":25},"Database","/docs/features/database","docs/2.features/01.database",{"title":27,"path":28,"stem":29},"Authentication","/docs/features/auth","docs/2.features/02.auth",{"title":31,"path":32,"stem":33},"Payments","/docs/features/payments","docs/2.features/03.payments",{"title":35,"path":36,"stem":37},"Admin Panel","/docs/features/admin-panel","docs/2.features/04.admin-panel",{"title":39,"path":40,"stem":41},"AI","/docs/features/ai","docs/2.features/05.ai",{"title":43,"path":44,"stem":45},"Customization","/docs/features/customization","docs/2.features/06.customization",{"title":47,"path":48,"stem":49},"Storage","/docs/features/storage","docs/2.features/07.storage",{"title":51,"path":52,"stem":53},"Email","/docs/features/email","docs/2.features/08.email",{"title":55,"path":56,"stem":57},"Languages","/docs/features/languages","docs/2.features/09.languages",{"title":59,"path":60,"stem":61},"SEO","/docs/features/seo","docs/2.features/10.seo",{"title":63,"path":64,"stem":65},"Blogs","/docs/features/blogs","docs/2.features/11.blogs",{"title":67,"path":68,"stem":69},"Documentation","/docs/features/documentation","docs/2.features/12.documentation",{"title":71,"path":72,"stem":73},"Cron Jobs","/docs/features/cron-jobs","docs/2.features/13.cron-jobs",{"title":75,"path":76,"stem":77},"Error Handling","/docs/features/error-handling","docs/2.features/14.error-handling",{"title":79,"path":80,"stem":81},"Analytics","/docs/features/analytics","docs/2.features/15.analytics",{"title":83,"path":84,"stem":85},"PWA","/docs/features/pwa","docs/2.features/15.pwa",{"title":87,"path":88,"stem":89},"Customer Support","/docs/features/customer-support","docs/2.features/16.customer-support",false,{"title":92,"icon":93,"path":94,"stem":95,"children":96,"page":90},"Tutorials","ic:baseline-library-books","/docs/tutorials","docs/3.tutorials",[97,101,105,109,113],{"title":98,"path":99,"stem":100},"Project Structure","/docs/tutorials/project-structure","docs/3.tutorials/1.project-structure",{"title":102,"path":103,"stem":104},"Page Routes","/docs/tutorials/page-routes","docs/3.tutorials/2.page-routes",{"title":106,"path":107,"stem":108},"API Calls","/docs/tutorials/api-calls","docs/3.tutorials/3.api-calls",{"title":110,"path":111,"stem":112},"State Management","/docs/tutorials/state-management","docs/3.tutorials/4.state-management",{"title":114,"path":115,"stem":116},"Legal Pages by GPT","/docs/tutorials/legal-pages-by-gpt","docs/3.tutorials/5.legal-pages-by-gpt",{"title":118,"icon":119,"path":120,"stem":121,"children":122,"page":90},"Formatting & Linting","ic:baseline-format-align-left","/docs/formatting-and-linting","docs/4.formatting-and-linting",[123],{"title":124,"path":125,"stem":126},"Overview","/docs/formatting-and-linting/overview","docs/4.formatting-and-linting/1.overview",{"title":128,"icon":129,"path":130,"stem":131,"children":132,"page":90},"Deployment","ic:baseline-rocket-launch","/docs/deployment","docs/5.deployment",[133,136,140],{"title":124,"path":134,"stem":135},"/docs/deployment/overview","docs/5.deployment/1.overview",{"title":137,"path":138,"stem":139},"Vercel","/docs/deployment/vercel","docs/5.deployment/2.vercel",{"title":141,"path":142,"stem":143},"Cloudflare Workers","/docs/deployment/cloudflare","docs/5.deployment/3.cloudflare",{"page":145,"surround":390},{"id":146,"title":47,"body":147,"description":382,"extension":383,"head":384,"meta":385,"navigation":386,"ogImage":384,"path":48,"robots":384,"schemaOrg":384,"seo":387,"sitemap":388,"stem":49,"__hash__":389},"docs_en/docs/2.features/07.storage.md",{"type":148,"value":149,"toc":375},"minimark",[150,155,175,178,281,285,293,363,367],[151,152,154],"h2",{"id":153},"tools","Tools",[156,157,158,168],"ul",{},[159,160,161,167],"li",{},[162,163,166],"a",{"href":164,"target":165},"https://www.cloudflare.com/products/r2","_blank","Cloudflare R2"," – simple and cost-effective storage (recommended)",[159,169,170,174],{},[162,171,173],{"href":172,"target":165},"https://aws.amazon.com/s3","AWS S3"," (or any S3-compatible service) – more advanced features",[151,176,12],{"id":177},"setup",[179,180,181,196,212,267],"ol",{},[159,182,183,184],{},"Choose a storage provider:",[156,185,186,191],{},[159,187,188,190],{},[162,189,166],{"href":164,"target":165}," – recommended for simplicity and low cost",[159,192,193,195],{},[162,194,173],{"href":172,"target":165}," (or compatible services like MinIO, DigitalOcean Spaces, etc.)",[159,197,198,199],{},"Create a bucket:",[156,200,201,204],{},[159,202,203],{},"Go to your provider’s dashboard and create a new bucket (folder for files)",[159,205,206,207,211],{},"Copy the ",[208,209,210],"strong",{},"credentials",": access key, secret key, bucket name, endpoint",[159,213,214,215],{},"Cloudflare R2 specific steps:",[179,216,217,223,239,253],{},[159,218,219,220],{},"Sign up / Sign in at ",[162,221,222],{"href":164,"target":165},"Cloudflare",[159,224,225,226],{},"Create a new R2 bucket:\n",[156,227,228,236],{},[159,229,230,231,235],{},"Pick a globally unique bucket name (e.g., ",[232,233,234],"code",{},"your-project-name",")",[159,237,238],{},"Select a region close to your target audience",[159,240,241,242],{},"Enable public access: Settings → Public Development URL → Enable\n",[156,243,244,250],{},[159,245,246,247],{},"Save the public URL as ",[232,248,249],{},"STORAGE_PUBLIC_URL",[159,251,252],{},"Optional: Set custom domains for added security",[159,254,255,256],{},"Create a new API Token:\n",[156,257,258,261,264],{},[159,259,260],{},"Storage & databases > R2 object storage > API Tokens > Manage, click Create User API Token",[159,262,263],{},"Set permissions to Object Read & Write to the bucket",[159,265,266],{},"Copy the Access Key ID and Secret Access Key",[159,268,269,270],{},"Set the following environment variables:",[271,272,279],"pre",{"className":273,"code":275,"filename":276,"language":277,"meta":278},[274],"language-text","S3_REGION=\"your-region\" # Use \"auto\" for R2, or e.g. \"us-east-1\" for S3\nS3_BUCKET=\"your-bucket-name\"\nS3_ACCESS_KEY_ID=\"your-access-key-id\"\nS3_SECRET_ACCESS_KEY=\"your-secret-access-key\"\nS3_ENDPOINT=\"your-s3-endpoint\" # Optional\nS3_PUBLIC_URL=\"https://cdn.yourdomain.com\" # Public URL (CDN or subdomain)\n",".env","text","",[232,280,275],{"__ignoreMap":278},[151,282,284],{"id":283},"usage","Usage",[286,287,288,289,292],"p",{},"Storage functions are available in the File Management module in the Admin Panel. Use the ",[232,290,291],{},"useApi"," composable:",[156,294,295,308,319,330,341,352],{},[159,296,297,300,301],{},[208,298,299],{},"List files",":",[271,302,306],{"className":303,"code":304,"filename":305,"language":277,"meta":278},[274],"const { getStorageFiles } = useApi();\nconst response = await getStorageFiles();\nconsole.log('File uploaded list:', response.data.blobs);\n","app/pages/admin/files.vue",[232,307,304],{"__ignoreMap":278},[159,309,310,300,313],{},[208,311,312],{},"Upload files",[271,314,317],{"className":315,"code":316,"filename":305,"language":277,"meta":278},[274],"const { uploadStorageFiles } = useApi();\nconst selectedFiles = ref\u003CFile[]>([]);\nconst response = await uploadStorageFiles(selectedFiles.value);\nconsole.log('File uploaded total:', response.data.success);\n",[232,318,316],{"__ignoreMap":278},[159,320,321,300,324],{},[208,322,323],{},"Download a File",[271,325,328],{"className":326,"code":327,"filename":305,"language":277,"meta":278},[274],"const { downloadStorageFile } = useApi();\nconst file = await downloadStorageFile('example.jpg');\n",[232,329,327],{"__ignoreMap":278},[159,331,332,300,335],{},[208,333,334],{},"Delete a File",[271,336,339],{"className":337,"code":338,"filename":305,"language":277,"meta":278},[274],"const { deleteStorageFile } = useApi();\nconst response = await deleteStorageFile('example.jpg');\nconsole.log('Deleted?', response.success);\n",[232,340,338],{"__ignoreMap":278},[159,342,343,300,346],{},[208,344,345],{},"Bulk delete files",[271,347,350],{"className":348,"code":349,"filename":305,"language":277,"meta":278},[274],"const { bulkDeleteStorageFile } = useApi();\nconst response = await bulkDeleteStorageFile(['example.jpg']);\nconsole.log('Deleted Total: ', response.data.success);\n",[232,351,349],{"__ignoreMap":278},[159,353,354,300,357],{},[208,355,356],{},"Access public file (CDN)",[271,358,361],{"className":359,"code":360,"filename":305,"language":277,"meta":278},[274],"const { public: pub } = useRuntimeConfig();\nconst imageUrl = `${pub.storagePublicUrl}/example.jpg`;\nconsole.log(imageUrl); // https://cdn.yourdomain.com/example.jpg\n",[232,362,360],{"__ignoreMap":278},[151,364,366],{"id":365},"best-practices","Best Practices",[156,368,369,372],{},[159,370,371],{},"File Size Limits: Set reasonable file size limits to prevent abuse",[159,373,374],{},"File Type Validation: Validate file types on both client and server sides for security",{"title":278,"searchDepth":376,"depth":376,"links":377},2,[378,379,380,381],{"id":153,"depth":376,"text":154},{"id":177,"depth":376,"text":12},{"id":283,"depth":376,"text":284},{"id":365,"depth":376,"text":366},"Easily set up file storage in your app with Cloudflare R2 or S3-compatible services to handle uploads, downloads, deletions, and public file access.","md",null,{},true,{"title":47,"description":382},{"loc":48},"6_s9trAFfp42eutXbCfMIzNOK-5ooEZRxuNXfYXSJvM",[391,393],{"title":43,"path":44,"stem":45,"description":392,"children":-1},"Customize the logo, colors, favicon, NuxtUI theme, and font family in your app to match your brand.",{"title":51,"path":52,"stem":53,"description":394,"children":-1},"Set up email in your app to send transactional emails like password resets and verification links."]