PageSourceSearch

https://local-uploads.r2-demo.workers.dev/

html local-uploads.r2-demo.workers.dev collected 2026-10-03 08:08:29 UTC 12,022 bytes, 69 lines download raw bytes

1<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" as="image" href="/CF-Logo 1.png"/>
1<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async="" defer=""></script>
1<title>R2 Local Uploads Demo</title><meta name="description" content="See the performance benefits of R2 Local Uploads"/><link rel="icon" type="image/png" href="/favicon.png"/><link rel="preconnect" href="https://fonts.googleapis.com"/><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin="anonymous"/><link rel="modulepreload" href="/assets/entry.client-BxWvKjUH.js"/><link rel="modulepreload" href="/assets/chunk-JMJ3UQ3L-O5Vcyypg.js"/><link rel="modulepreload" href="/assets/root-CTov3YhH.js"/><link rel="modulepreload" href="/assets/home-Dr2oDBhj.js"/><link rel="stylesheet" href="/assets/root-Zspsc9VA.css"/><link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&amp;display=swap"/></head><body><main class="h-screen flex flex-col bg-white text-gray-900 overflow-hidden"><header class="flex-none flex items-center justify-between px-4 py-3 lg:px-6 lg:py-4 bg-white border-b border-gray-200"><div class="flex items-center gap-3 lg:gap-4"><a href="https://workers.cloudflare.com/product/r2/" target="_blank" rel="noopener noreferrer"><img src="/CF-Logo 1.png" alt="Cloudflare" class="h-5 lg:h-6 w-auto"/></a><span class="text-gray-300">|</span><span class="text-xs lg:text-sm font-medium text-gray-600">Cloudflare R2 Local Uploads</span></div><a href="https://developers.cloudflare.com/r2/buckets/local-uploads/" target="_blank" rel="noopener noreferrer" class="text-xs lg:text-sm text-gray-500 hover:text-orange-500 flex items-center gap-1">Docs<svg class="w-3 lg:w-3.5 h-3 lg:h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"></path></svg></a></header><div class="flex-1 flex flex-col lg:flex-row min-h-0"><div class="flex-1 flex flex-col min-h-0 order-1 lg:order-2 h-[45vh] lg:h-auto"><div class="flex-1 relative overflow-hidden bg-white"><div class="absolute inset-0 pointer-events-none" style="background-image:radial-gradient(circle, rgba(243, 128, 32, 0.25) 1.5px, transparent 1.5px),
2                  radial-gradient(circle, rgba(243, 128, 32, 0.18) 1px, transparent 1px),
3                  radial-gradient(circle, rgba(243, 128, 32, 0.1) 0.5px, transparent 0.5px);background-size:80px 80px, 40px 40px, 20px 20px;background-position:0 0, 20px 20px, 10px 10px"></div><div class="absolute inset-0 flex items-center justify-center overflow-hidden"><div id="globe-container" style="width:230%;height:230%"></div><div class="absolute inset-0 flex items-center justify-center bg-white"><div class="flex flex-col items-center gap-3"><div class="w-8 h-8 border-2 border-orange-200 border-t-orange-500 rounded-full animate-spin"></div><span class="text-gray-400 text-sm">Loading globe...</span></div></div></div><div class="absolute top-2 right-2 lg:top-4 lg:right-4 bg-white/90 backdrop-blur-sm rounded px-2 py-1.5 lg:px-3 lg:py-2 shadow-sm border border-gray-100"><div class="flex flex-row lg:flex-col gap-2 lg:gap-1.5 text-[9px] lg:text-xs text-gray-600"><div class="flex items-center gap-1.5 lg:gap-2"><div class="flex flex-col gap-1 flex-shrink-0"><div class="w-4 lg:w-5 h-0.5 bg-orange-500 rounded-full"></div><div class="w-4 lg:w-5 h-0.5 bg-gray-400 rounded-full"></div></div><span class="whitespace-nowrap">Direct</span></div><div class="flex items-center gap-1.5 lg:gap-2"><div class="w-4 lg:w-5 h-0.5 rounded-full flex-shrink-0" style="background:repeating-linear-gradient(90deg, #F8AD4C 0, #F8AD4C 2px, transparent 2px, transparent 4px)"></div><span class="whitespace-nowrap">Async replication</span></div></div></div></div></div><div class="order-3 lg:order-1 w-full lg:w-80 xl:w-96 flex-none flex flex-col p-4 lg:p-6 border-t lg:border-t-0 lg:border-r border-gray-200 bg-[#fafafa]" style="background-image:radial-gradient(circle, rgba(0, 0, 0, 0.08) 1px, transparent 1px);background-size:16px 16px"><div class="mb-4 lg:mb-6"><div class="group relative inline-block"><p class="text-xs font-bold tracking-[0.3em] text-orange-500 mb-1 lg:mb-2 flex items-center gap-2"><span class="text-[9px] font-semibold tracking-normal px-1.5 py-0.5 bg-orange-100 text-orange-600 rounded">BETA</span>LOCAL UPLOADS<button class="text-gray-400 hover:text-orange-400 transition-colors">ⓘ</button></p><div class="absolute left-0 top-full mt-1 px-3 py-2 bg-gray-900 text-white text-xs rounded-lg transition-opacity pointer-events-auto w-72 z-50 opacity-0 lg:group-hover:opacity-100 pointer-events-none lg:pointer-events-auto">Local Uploads writes object data to a nearby storage then asynchronously copies it to your bucket – all while data is available immediately. <a href="https://developers.cloudflare.com/r2/buckets/local-uploads/" target="_blank" rel="noopener noreferrer" class="text-orange-300 hover:text-orange-200 underline">Learn more</a>.<div class="absolute bottom-full right-20 border-4 border-transparent border-b-gray-900"></div></div></div><p class="text-sm lg:text-lg text-gray-700">Improve cross-region upload performance in R2 with Local Uploads.</p></div><div class="flex items-center gap-2 text-[11px] lg:text-sm text-gray-500 mb-3 lg:mb-6 pb-3 lg:pb-6 border-b border-gray-200"><svg class="w-4 h-4 flex-shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z"></path><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 11a3 3 0 11-6 0 3 3 0 016 0z"></path></svg><span class="text-gray-400">Detecting location...</span></div><div class="space-y-2 lg:space-y-4 mb-3 lg:mb-6"><div class="flex flex-row lg:flex-col gap-2 lg:gap-4"><div class="flex-1"><div class="flex items-center gap-1.5 mb-2"><label class="text-[10px] lg:text-xs font-medium text-gray-500">FILE SIZE</label><div class="relative"><button class="hover:text-gray-600"><svg class="w-3.5 h-3.5 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg></button></div></div><select class="lg:hidden cf-select w-full px-2 py-2 text-xs rounded-md border border-gray-200 bg-white text-gray-900 focus:outline-none focus:border-orange-500 cursor-pointer"><option value="large">50 MB</option><option value="medium" selected="">5 MB</option><option value="small">100 KB</option></select><div class="hidden lg:flex relative gap-2 bg-white rounded-md border border-gray-200"><div class="absolute top-0 bottom-0 bg-orange-100 rounded-md transition-all duration-200 ease-out" style="width:calc(100% / 3);left:calc(1 * 100% / 3)"></div><button class="relative z-10 flex-1 py-2 px-3 text-center rounded-md transition-colors duration-200 text-sm text-gray-600 hover:text-gray-900">50 MB</button><button class="relative z-10 flex-1 py-2 px-3 text-center rounded-md transition-colors duration-200 text-sm text-orange-600 font-medium">5 MB</button><button class="relative z-10 flex-1 py-2 px-3 text-center rounded-md transition-colors duration-200 text-sm text-gray-600 hover:text-gray-900">100 KB</button></div></div><div class="flex-1"><div class="flex items-center gap-1.5 mb-2"><label class="text-[10px] lg:text-xs font-medium text-gray-500">BUCKET REGION</label><div class="relative"><button class="hover:text-gray-600"><svg class="w-3.5 h-3.5 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg></button></div></div><select class="cf-select w-full px-2 lg:px-3 py-2 text-xs lg:text-sm rounded-md border border-gray-200 bg-white text-gray-900 focus:outline-none focus:border-orange-500 cursor-pointer"><option value="wnam">Western North America</option><option value="enam">Eastern North America</option><option value="weur">Western Europe</option><option value="eeur" selected="">Eastern Europe</option><option value="apac">Asia Pacific</option><option value="oc">Oceania</option></select></div></div><div class="pt-2 pb-2 lg:pt-0 lg:pb-0"><button disabled="" class="cf-button-primary w-full !text-sm lg:!text-base font-normal whitespace-nowrap !py-2 lg:!py-3">Complete verification below</button></div><div class="flex flex-col items-center gap-1 lg:gap-2"><div class="scale-75 lg:scale-100 origin-center -my-2 lg:my-0"></div></div></div><div class="mt-auto pt-4 border-t border-gray-200"><p class="text-[8px] lg:text-[10px] text-gray-400 leading-relaxed">
3This demo illustrates the relative benefit of Local Uploads. Uploads are performed server-side from a Cloudflare Worker close to you. <em>Results may vary depending on network conditions and server load.</em></p></div></div></div></main>
3<script>((storageKey2, restoreKey) => {
4    if (!window.history.state || !window.history.state.key) {
5      let key = Math.random().toString(32).slice(2);
6      window.history.replaceState({ key }, "");
7    }
8    try {
9      let positions = JSON.parse(sessionStorage.getItem(storageKey2) || "{}");
10      let storedY = positions[restoreKey || window.history.state.key];
11      if (typeof storedY === "number") {
12        window.scrollTo(0, storedY);
13      }
14    } catch (error) {
15      console.error(error);
16      sessionStorage.removeItem(storageKey2);
17    }
18  })("react-router-scroll-positions", null)</script>
18<script>window.__reactRouterContext = {"basename":"/","future":{"unstable_optimizeDeps":false,"unstable_subResourceIntegrity":false,"v8_middleware":false,"v8_splitRouteModules":false,"v8_viteEnvironmentApi":true},"routeDiscovery":{"mode":"lazy","manifestPath":"/__manifest"},"ssr":true,"isSpaMode":false};window.__reactRouterContext.stream = new ReadableStream({start(controller){window.__reactRouterContext.streamController = controller;}}).pipeThrough(new TextEncoderStream());</script>
18<script type="module" async="">;
19import * as route0 from "/assets/root-CTov3YhH.js";
20import * as route1 from "/assets/home-Dr2oDBhj.js";
21  window.__reactRouterManifest = {
22  "entry": {
23    "module": "/assets/entry.client-BxWvKjUH.js",
24    "imports": [
25      "/assets/chunk-JMJ3UQ3L-O5Vcyypg.js"
26    ],
27    "css": []
28  },
29  "routes": {
30    "root": {
31      "id": "root",
32      "path": "",
33      "hasAction": false,
34      "hasLoader": false,
35      "hasClientAction": false,
36      "hasClientLoader": false,
37      "hasClientMiddleware": false,
38      "hasErrorBoundary": true,
39      "module": "/assets/root-CTov3YhH.js",
40      "imports": [
41        "/assets/chunk-JMJ3UQ3L-O5Vcyypg.js"
42      ],
43      "css": [
44        "/assets/root-Zspsc9VA.css"
45      ]
46    },
47    "routes/home": {
48      "id": "routes/home",
49      "parentId": "root",
50      "index": true,
51      "hasAction": false,
52      "hasLoader": true,
53      "hasClientAction": false,
54      "hasClientLoader": false,
55      "hasClientMiddleware": false,
56      "hasErrorBoundary": false,
57      "module": "/assets/home-Dr2oDBhj.js",
58      "imports": [
59        "/assets/chunk-JMJ3UQ3L-O5Vcyypg.js"
60      ],
61      "css": []
62    }
63  },
64  "url": "/assets/manifest-e0c67d17.js",
65  "version": "e0c67d17"
66};
67  window.__reactRouterRouteModules = {"root":route0,"routes/home":route1};
68
69import("/assets/entry.client-BxWvKjUH.js");</script>
69<!--$-->
69<script>window.__reactRouterContext.streamController.enqueue("[{\"_1\":2,\"_7\":-5,\"_8\":-5},\"loaderData\",{\"_3\":4},\"routes/home\",{\"_5\":6},\"turnstileSiteKey\",\"0x4AAAAAACUT3pff4fSNupbv\",\"actionData\",\"errors\"]\n");</script>
69<!--$-->
69<script>window.__reactRouterContext.streamController.close();</script>
69<!--/$--><!--/$--></body></html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.