Closed pie6k closed 7 months ago
@pie6k Sorry you're hitting this limitation, I am glad you're willing to upload large files from Node.js directly.
To solve your issue, you can use the normal put
method, I'll explain why right after:
// use multipart is the upload is large (> 10MB for example)
const blob = await put(filename, content, { access: 'public', multipart: true });
A few notes:
import { generateClientTokenFromReadWriteToken } from '@vercel/blob/client';
import { put } from '@vercel/blob';
const clientToken = await client.generateClientTokenFromReadWriteToken({
token, // read write token
pathname: 'file.txt',
// onUploadCompleted: {
// callbackUrl: 'https://yourwebsite.com/upload-complete',
// },
});
const blob = await put('file.txt', content, { access: 'public', multipart: 'true', token: clientToken });
Let me know if this makes sense to you now and if you think we should make more changes to documentation or API. Thanks!
Ok, indeed I just passed this token into options of put. Works like a charm! Thanks a lot!
Nit: would be lovely to be able to track upload progress (currently I simulate it assuming 1Mbps upload speed 👾)
clientToken
@pie6k Sorry you're hitting this limitation, I am glad you're willing to upload large files from Node.js directly.
To solve your issue, you can use the normal
put
method, I'll explain why right after:// use multipart is the upload is large (> 10MB for example) const blob = await put(filename, content, { access: 'public', multipart: true });
A few notes:
- The 4.5 MB limitation you're talking about is only relative to when you deploy a website to Vercel, and you have a route that accepts files. Then this route can only accept files up to 4.5 MB. In this case you want to use client uploads yes.
- We will probably get rid of this window check, this is where most of the libraries are going nowadays (client and server definitions are more and more blurry, so anything can be client or server)
- If you really want to use client uploads from your Electron app, perhaps because you don't want to store your Blob read write token in the app when distributing it, then you can still do it this way:
import { generateClientTokenFromReadWriteToken } from '@vercel/blob/client'; import { put } from '@vercel/blob'; const clientToken = await client.generateClientTokenFromReadWriteToken({ token, // read write token pathname: 'file.txt', // onUploadCompleted: { // callbackUrl: 'https://yourwebsite.com/upload-complete', // }, }); const blob = await put('file.txt', content, { access: 'public', multipart: 'true' });
Let me know if this makes sense to you now and if you think we should make more changes to documentation or API. Thanks!
@vvo Where is the clientToken
used?
@sajeeIfonix I forgot to use it in the example, now fixed, here it is updated:
import { generateClientTokenFromReadWriteToken } from '@vercel/blob/client';
import { put } from '@vercel/blob';
const clientToken = await client.generateClientTokenFromReadWriteToken({
token, // read write token
pathname: 'file.txt',
// onUploadCompleted: {
// callbackUrl: 'https://yourwebsite.com/upload-complete',
// },
});
const blob = await put('file.txt', content, { access: 'public', multipart: 'true', token: clientToken });
Hope this helps. BTW what's your usecase for client uploads from server? Thanks!
@sajeeIfonix I forgot to use it in the example, now fixed, here it is updated:
import { generateClientTokenFromReadWriteToken } from '@vercel/blob/client'; import { put } from '@vercel/blob'; const clientToken = await client.generateClientTokenFromReadWriteToken({ token, // read write token pathname: 'file.txt', // onUploadCompleted: { // callbackUrl: 'https://yourwebsite.com/upload-complete', // }, }); const blob = await put('file.txt', content, { access: 'public', multipart: 'true', token: clientToken });
Hope this helps. BTW what's your usecase for client uploads from server? Thanks!
Hello @vvo ,
Thanks for the clarification.
I have a react native mobile application. I want to upload images and PDFs from the mobile app to Vercel blob. What I understand from your code snippet is,
READ-WRITE
token from the server.Have I understood the task correctly?
I have a react native mobile application
Can you create a new issue then with more details? Ideally on React Native you can just use https://vercel.com/docs/storage/vercel-blob/client-upload directly without any issue, can you try that?
I need to request for the READ-WRITE token from the server.
Ideally no, your VERCEL_BLOB_READ_WRITE_TOKEN is sensitive and thus should never be sent to a client (react native, electron app, browser...), instead use client uploads either with our built-in upload() and handleUpload() methods or manually by creating an endpoint on your side that generate client tokens and send them to clients (react native) to then be used in a normal put()
I have a react native mobile application
Can you create a new issue then with more details? Ideally on React Native you can just use https://vercel.com/docs/storage/vercel-blob/client-upload directly without any issue, can you try that?
I tried to do this previously. However, i am facing this GutHub issue https://github.com/vercel/storage/issues/505. So i was looking at your snippet for a work around.
I think the window
check should just be removed. It works fine if you do this hack before using upload(...)
(in nodejs, likely an equivalent way to set a global variable would work in React Native/Electron etc.):
Object.assign{global, {window: new URL('https://mywebsite.com')})
Which suggests the check is only for its own sake- there's nothing else that depends on browser-specific APIs. And removing it would allow client uploading from various clients which aren't browsers (React Native, Electron, CLIs, GitHub Actions, etc. etc.) - without having to build a custom flow and risk confusing people into putting their read-write token somewhere unsafe. Users will be able to just follow the docs for client uploads.
Use case:
I want to upload files larger than 4.5MB (vercel limit) from node.js enviroment (to be specific - from Electron main process which runs in node env)
I did follow steps at https://vercel.com/docs/storage/vercel-blob/client-upload and it works perfectly fine, but I'm only able to run it from browser env.
If I run it in node env I hit
${methodName} must be called from a client environment
error. (https://github.com/vercel/storage/blob/5fb6969801107030adbdd156a1a1f2da8414eaad/packages/blob/src/client.ts#L52)I did check the file https://github.com/vercel/storage/blob/5fb6969801107030adbdd156a1a1f2da8414eaad/packages/blob/src/client.ts and it seems to barely be using
window
, the only real case isI think it might be quite common use case to handle such uploads externally. Is there any particular reason this use-case is restricted to Browser env?