@@ -4,3 +4,175 @@ description: How to store objects with NuxtHub.
4
4
---
5
5
6
6
NuxtHub Blob is a layer to [ Cloudflare R2] ( https://developers.cloudflare.com/r2 ) , allowing to store large amounts of unstructured data.
7
+
8
+ <!-- TODO: config, binding ? -->
9
+
10
+ Once properly configured, NuxtHub module exposes a server composable to the application.
11
+
12
+ ## ` useBlob() `
13
+
14
+ Server composable that returns a set of methods to manipulate the blob storage.
15
+
16
+ ### ` list() `
17
+
18
+ Returns a paginated list of blobs.
19
+
20
+ ``` ts[/api/blob/index.get.ts]
21
+ export default eventHandler(async () => {
22
+ return useBlob().list()
23
+ })
24
+ ```
25
+
26
+ #### Params
27
+
28
+ - ` options ` : [ ` BlobListOptions ` ] ( #bloblistoptions )
29
+
30
+ #### Return
31
+
32
+ Returns an array of [ ` BlobObject ` ] ( #blobobject ) .
33
+
34
+ ### ` serve() `
35
+
36
+ Returns a blob's data.
37
+
38
+ ``` ts[/api/blob/[...pathname\\ ].get.ts]
39
+ export default eventHandler(async (event) => {
40
+ const { pathname } = getRouterParams(event)
41
+
42
+ return useBlob().serve(event, pathname)
43
+ })
44
+ ```
45
+
46
+ #### Params
47
+
48
+ - ` event ` : [ ` H3Event ` ] ( https://github.com/unjs/h3 )
49
+ - ` pathname ` : ` string `
50
+
51
+ #### Return
52
+
53
+ Returns the blob's raw data and sets ` Content-Type ` and ` Content-Length ` headers.
54
+
55
+ :: callout { icon =" i-heroicons-information-circle " }
56
+ If you are fetching an image with a server route similar to the one above, you might simply want to use it this way:
57
+ <br >
58
+ ``` vue
59
+ <img :src="`/api/blob/${file.pathname}`">
60
+ ```
61
+ ::
62
+
63
+ ### ` head() `
64
+
65
+ Returns a blob's metadata.
66
+
67
+ ``` ts[/api/blob/[...pathname\\ ].head.ts]
68
+ export default eventHandler(async (event) => {
69
+ const { pathname } = getRouterParams(event)
70
+
71
+ const blob = await useBlob().head(pathname)
72
+
73
+ setHeader(event, 'x-blob', JSON.stringify(blob))
74
+
75
+ return sendNoContent(event)
76
+ })
77
+ ```
78
+
79
+ #### Params
80
+
81
+ - ` pathname ` : ` string `
82
+
83
+ #### Return
84
+
85
+ Returns a [ ` BlobObject ` ] ( #blobobject ) .
86
+
87
+ ### ` put() `
88
+
89
+ Uploads a blob.
90
+
91
+ ``` ts[/api/blob/[...pathname\\ ].put.ts]
92
+ export default eventHandler(async (event) => {
93
+ const { pathname } = getRouterParams(event)
94
+ const form = await readFormData(event)
95
+ const file = form.get('file') as Blob
96
+
97
+ if (!file || !file.size) {
98
+ throw createError({ statusCode: 400, message: 'No file provided' })
99
+ }
100
+
101
+ ensureBlob(file, { maxSize: '1MB', types: ['image' ]})
102
+
103
+ return useBlob().put(`images/${file.name}`, file, { addRandomSuffix: false })
104
+ })
105
+ ```
106
+
107
+ #### Params
108
+
109
+ - ` pathname ` : ` string `
110
+ - ` body ` : ` string ` | ` ReadableStream<any> ` | ` ArrayBuffer ` | ` ArrayBufferView ` | ` Blob `
111
+ - ` options ` : [ ` BlobPutOptions ` ] ( #blobputoptions )
112
+ #### Return
113
+
114
+ Returns a [ ` BlobObject ` ] ( #blobobject ) .
115
+
116
+ :: callout { icon =" i-heroicons-light-bulb " }
117
+ Take a look at all the [ validation] ( /recipes/validation ) utils like [ ` ensureBlob ` ] ( /recipes/validation#ensureblob )
118
+ ::
119
+
120
+ ### ` delete() `
121
+
122
+ Deletes a blob.
123
+
124
+ ``` ts[/api/blob/[...pathname\\ ].delete.ts]
125
+ export default eventHandler(async (event) => {
126
+ const { pathname } = getRouterParams(event)
127
+
128
+ await useBlob().delete(pathname)
129
+
130
+ return sendNoContent(event)
131
+ })
132
+ ```
133
+
134
+ #### Params
135
+
136
+ - ` pathname ` : ` string `
137
+
138
+ #### Return
139
+
140
+ Returns nothing.
141
+
142
+ ## Types
143
+
144
+ ### ` BlobListOptions `
145
+
146
+ ``` ts
147
+ interface BlobListOptions {
148
+ /**
149
+ * The maximum number of blobs to return per request.
150
+ * @default 1000
151
+ */
152
+ limit? : number
153
+ prefix? : string
154
+ cursor? : string
155
+ }
156
+ ```
157
+
158
+ ### ` BlobPutOptions `
159
+
160
+ ``` ts
161
+ interface BlobPutOptions {
162
+ contentType? : string ,
163
+ contentLength? : string ,
164
+ addRandomSuffix? : boolean ,
165
+ [key : string ]: any
166
+ }
167
+ ```
168
+
169
+ ### ` BlobObject `
170
+
171
+ ``` ts
172
+ interface BlobObject {
173
+ pathname: string
174
+ contentType: string | undefined
175
+ size: number
176
+ uploadedAt: Date
177
+ }
178
+ ```
0 commit comments