0xtech
0xtech11mo ago

How to get image url after uploaded image ?

const handleAvatarUpload = useCallback(async (file: File) => {
try {
setUploadLoading(true);
const postUrl = await generateUploadUrl();
// Step 2: POST the file to the URL
const result = await fetch(postUrl, {
method: "POST",
headers: { "Content-Type": file!.type },
body: file,
});

const { storageId } = await result.json();
} catch (error) {
toast("Something went wrong", {
description: "Our support team has been notified",
});
console.error("Failed to update user profile", error);
}
}, []);
const handleAvatarUpload = useCallback(async (file: File) => {
try {
setUploadLoading(true);
const postUrl = await generateUploadUrl();
// Step 2: POST the file to the URL
const result = await fetch(postUrl, {
method: "POST",
headers: { "Content-Type": file!.type },
body: file,
});

const { storageId } = await result.json();
} catch (error) {
toast("Something went wrong", {
description: "Our support team has been notified",
});
console.error("Failed to update user profile", error);
}
}, []);
I wanna get image url with stroage id after I uploaded image
7 Replies
0xtech
0xtechOP11mo ago
const convexSiteUrl = import.meta.env.VITE_CONVEX_SITE_URL;

function Image({ storageId }: { storageId: string }) {
// e.g. https://happy-animal-123.convex.site/getImage?storageId=456
const getImageUrl = new URL(`${convexSiteUrl}/getImage`);
getImageUrl.searchParams.set("storageId", storageId);

return <img src={getImageUrl.href} height="300px" width="auto" />;
}
const convexSiteUrl = import.meta.env.VITE_CONVEX_SITE_URL;

function Image({ storageId }: { storageId: string }) {
// e.g. https://happy-animal-123.convex.site/getImage?storageId=456
const getImageUrl = new URL(`${convexSiteUrl}/getImage`);
getImageUrl.searchParams.set("storageId", storageId);

return <img src={getImageUrl.href} height="300px" width="auto" />;
}
I tried but it's not working with 404 issue https://precious-yak-175.convex.cloud this is my development convex url
Michal Srb
Michal Srb11mo ago
Thanks for the details. Where did you get the idea that https://happy-animal-123.convex.site/getImage?storageId=456 should work?
Michal Srb
Michal Srb11mo ago
Ah, from the bottom of the docs. For that to work you need to set up the HTTP action. Alternatively you can use a query: https://docs.convex.dev/file-storage/serve-files#generating-file-urls-in-queries
Serving Files | Convex Developer Hub
Files stored in Convex can be served to your users by generating a URL pointing
Michal Srb
Michal Srb11mo ago
From your first snippet, it also looks like you're not storing the Storage ID in the database. You might want to do that:
// Write a mutation for saving the storage ID
const saveStorageId = useMutation(api.foo.bla);

// ...

// Use it after the successful upload
await saveStorageId({storageId, someOtherArgument});

// In a query generate the URL for serving:
url: await ctx.storage.getUrl(someDocument.storageId)

// Use it on the frontend
const data = useQuery(api.foo.buzz)
return <img src={data.url} />;
// Write a mutation for saving the storage ID
const saveStorageId = useMutation(api.foo.bla);

// ...

// Use it after the successful upload
await saveStorageId({storageId, someOtherArgument});

// In a query generate the URL for serving:
url: await ctx.storage.getUrl(someDocument.storageId)

// Use it on the frontend
const data = useQuery(api.foo.buzz)
return <img src={data.url} />;
0xtech
0xtechOP11mo ago
@Michal Srb yeah I tried with useQuery but here is issue since useQuery is hook I can only call in the component not function
export const getImageUrl = query({
args: { imageId: v.id("_storage") },
handler: async (ctx, args) => {
return await ctx.storage.getUrl(args.imageId);
},
});
export const getImageUrl = query({
args: { imageId: v.id("_storage") },
handler: async (ctx, args) => {
return await ctx.storage.getUrl(args.imageId);
},
});
so I made query and it's getting storageId as a argument
const [storageId, setStorageId] = useState('');
const getImageUrl = useMutation(
api.routes.userProfiles.queries.getImageUrl,
{
imageId: storageId
}
);
const [storageId, setStorageId] = useState('');
const getImageUrl = useMutation(
api.routes.userProfiles.queries.getImageUrl,
{
imageId: storageId
}
);
so calling query like it but as you can see storageId is empty string at first so it's getting issue
const handleAvatarUpload = useCallback(async (file: File) => {
try {
setUploadLoading(true);
const postUrl = await generateUploadUrl();
// Step 2: POST the file to the URL
const result = await fetch(postUrl, {
method: "POST",
headers: { "Content-Type": file!.type },
body: file,
});

const { storageId } = await result.json();
setStorageI(storageId);
} catch (error) {
toast("Something went wrong", {
description: "Our support team has been notified",
});
console.error("Failed to update user profile", error);
}
}, []);
const handleAvatarUpload = useCallback(async (file: File) => {
try {
setUploadLoading(true);
const postUrl = await generateUploadUrl();
// Step 2: POST the file to the URL
const result = await fetch(postUrl, {
method: "POST",
headers: { "Content-Type": file!.type },
body: file,
});

const { storageId } = await result.json();
setStorageI(storageId);
} catch (error) {
toast("Something went wrong", {
description: "Our support team has been notified",
});
console.error("Failed to update user profile", error);
}
}, []);
so setting storage id on here how can I define state value as a Storage Id ?
Michal Srb
Michal Srb11mo ago
If you don't want to store the storage ID and you just want the URL, you can either use a mutation or:
const client = useConvex();

// ... in your callback

await client.query(api.getMeURL, {storageId});
const client = useConvex();

// ... in your callback

await client.query(api.getMeURL, {storageId});
See https://docs.convex.dev/client/react#one-off-queries
Convex React | Convex Developer Hub
Convex React is the client library enabling your React application to interact
0xtech
0xtechOP11mo ago
yeah it's working thank you

Did you find this page helpful?