Skip to content

Commit d22d953

Browse files
authored
feat: Svelte support (#8)
1 parent eb08f6a commit d22d953

File tree

4 files changed

+3776
-4
lines changed

4 files changed

+3776
-4
lines changed

README.md

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
Store and serve files with Cloudflare R2.
88

99
```ts
10+
// or @convex-dev/r2/svelte for Svelte!
11+
import { useUploadFile } from "@convex-dev/r2/react";
12+
1013
// Upload files from React
1114
const uploadFile = useUploadFile(api.example);
1215
// ...in a callback
@@ -90,8 +93,7 @@ npx convex env set R2_BUCKET xxxxx
9093

9194
## Uploading files
9295

93-
File uploads to R2 typically use signed urls. The R2 component provides a React
94-
hook that handles the entire upload processs:
96+
File uploads to R2 typically use signed urls. The R2 component provides hooks for React and Svelte that handle the entire upload process:
9597

9698
- generates the signed url
9799
- uploads the file to R2
@@ -121,7 +123,9 @@ hook that handles the entire upload processs:
121123
});
122124
```
123125

124-
2. Use the `useUploadFile` hook in a React component to upload files:
126+
2. Use the `useUploadFile` hook in your component to upload files:
127+
128+
React:
125129

126130
```tsx
127131
// src/App.tsx
@@ -165,6 +169,40 @@ hook that handles the entire upload processs:
165169
}
166170
```
167171

172+
Svelte:
173+
174+
```svelte
175+
<script lang="ts">
176+
import { useUploadFile } from "@convex-dev/r2/svelte";
177+
import { api } from "../convex/_generated/api";
178+
179+
const uploadFile = useUploadFile(api.example);
180+
181+
let selectedImage = $state<File | null>(null);
182+
183+
async function handleUpload(file: File) {
184+
await uploadFile(file);
185+
selectedImage = null;
186+
}
187+
</script>
188+
189+
<form
190+
onsubmit={() => {
191+
if (selectedImage) handleUpload(selectedImage);
192+
}}
193+
>
194+
<input
195+
type="file"
196+
accept="image/*"
197+
onchange={(e) => {
198+
selectedImage = e.currentTarget.files?.[0] ?? null;
199+
}}
200+
disabled={selectedImage !== null}
201+
/>
202+
<button type="submit" disabled={selectedImage === null}> Upload </button>
203+
</form>
204+
```
205+
168206
### Using a custom object key
169207

170208
The `r2.generateUploadUrl` function generates a uuid to use as the object key by
@@ -379,7 +417,7 @@ export const page = query({
379417
### Accessing metadata after upload
380418

381419
The `onSyncMetadata` callback can be used to run a mutation after every metadata
382-
sync. The `useUploadFile` React hook syncs metadata after every upload, so this
420+
sync. The `useUploadFile` hook syncs metadata after every upload, so this
383421
function will run each time as well.
384422

385423
Because this runs after metadata sync, the `r2.getMetadata` can be used to

package.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,18 @@
5858
"default": "./dist/commonjs/react/index.js"
5959
}
6060
},
61+
"./svelte": {
62+
"import": {
63+
"@convex-dev/component-source": "./src/svelte/index.ts",
64+
"types": "./dist/esm/svelte/index.d.ts",
65+
"default": "./dist/esm/svelte/index.js"
66+
},
67+
"require": {
68+
"@convex-dev/component-source": "./src/svelte/index.ts",
69+
"types": "./dist/commonjs/svelte/index.d.ts",
70+
"default": "./dist/commonjs/svelte/index.js"
71+
}
72+
},
6173
"./convex.config": {
6274
"import": {
6375
"@convex-dev/component-source": "./src/component/convex.config.ts",
@@ -68,6 +80,8 @@
6880
},
6981
"peerDependencies": {
7082
"convex": "~1.16.5 || >=1.17.0 <1.35.0",
83+
"convex-svelte": "^0.0.11",
84+
"svelte": ">=5.0.0",
7185
"react": "^18 || ^19",
7286
"react-dom": "^18 || ^19"
7387
},

0 commit comments

Comments
 (0)