diff --git a/docs/capabilities/server/media-uploads.mdx b/docs/capabilities/server/media-uploads.mdx
index 7316f1a7..eda4b7d1 100644
--- a/docs/capabilities/server/media-uploads.mdx
+++ b/docs/capabilities/server/media-uploads.mdx
@@ -1,15 +1,12 @@
-import Tabs from '@theme/Tabs';
-import TabItem from '@theme/TabItem';
-
# Media Uploads
:::warning
-Apps can only display images hosted on Reddit
+Apps can only display media hosted on Reddit
:::
-You can upload images to Reddit at runtime using the `media` capability. This is different than static images, which are part of your [assets](../blocks/app_image_assets.md).
+You can upload media to Reddit at runtime using the `media` capability. This is different than static images, which are part of your [assets](../blocks/app_image_assets.md).
-Runtime images are useful for embedding images in RTJSON (Posts and Comments) as well as displaying them within an interactive post app.
+Runtime media is useful for embedding media in RTJSON (Posts and Comments) as well as displaying it within an interactive post app.
## Enabling media uploads
Enable the `media` permission in your `devvit.json` file.
@@ -21,32 +18,152 @@ Enable the `media` permission in your `devvit.json` file.
}
```
-## Using media uploads
-On the server, you can pass the URL of any remotely hosted image (even if its not hosted on Reddit) to the `media.upload` function. This function will return a Reddit URL. Both HTTP and data URLs are supported.
-
-
-
- ```ts title="server/index.ts"
- import { media } from '@devvit/media';
- function submitImage() {
- const response = await media.upload({
- url: 'https://media2.giphy.com/media/xTiN0CNHgoRf1Ha7CM/giphy.gif',
- type: 'gif',
+## Media uploads (Devvit Web)
+On the server, pass a remote URL or data URL to `media.upload()` to upload an image, GIF, or video and get a Reddit-hosted asset you can safely render in posts, comments, and rich text.
+
+### Response type
+`media.upload()` returns:
+
+```ts
+type MediaAsset = {
+ mediaId: string;
+ mediaUrl: string;
+};
+```
+
+- `mediaId`: Reddit media asset ID.
+- `mediaUrl`: Reddit CDN URL (use this in rich text or UI).
+
+### `media.upload()` input
+`media.upload()` expects an object with:
+
+- `url`: The media URL (remote URL or data URL).
+- `type`: The media kind (`'image'`, `'gif'`, or `'video'`).
+
+```ts
+type UploadMediaOptions = {
+ url: string; // remote URL or data URL
+ type: 'image' | 'gif' | 'video';
+};
+```
+
+Use `type: 'image'` for PNG, JPEG, and WEBP uploads.
+
+### Basic server usage
+```ts title="server/index.ts"
+import { media } from '@devvit/web/server';
+
+const uploaded = await media.upload({
+ url: 'https://example.com/my-image.png',
+ type: 'image',
+});
+
+// uploaded.mediaId
+// uploaded.mediaUrl
+```
+
+### Example: API endpoint returning upload response
+```ts title="server/index.ts"
+import { media } from '@devvit/web/server';
+
+app.post('/api/upload', async (c) => {
+ const { url, type } = await c.req.json<{
+ url: string;
+ type: 'image' | 'gif' | 'video';
+ }>();
+
+ const uploaded = await media.upload({ url, type });
+
+ return c.json({
+ mediaId: uploaded.mediaId,
+ mediaUrl: uploaded.mediaUrl,
+ });
+});
+```
+
+### Example: submit a post with uploaded media using RichTextBuilder
+```ts title="server/index.ts"
+import { media } from '@devvit/web/server';
+import { reddit, RichTextBuilder } from '@devvit/reddit';
+
+const uploaded = await media.upload({
+ url: 'https://example.com/cover.png',
+ type: 'image',
+});
+
+const richtext = new RichTextBuilder()
+ .paragraph((p) => {
+ p.text({ text: 'Uploaded image:' });
+ })
+ .paragraph((p) => {
+ p.image({
+ mediaUrl: uploaded.mediaUrl,
+ caption: 'Rendered from media.upload()',
});
- }
- ```
-
-
- ```ts
- import { Devvit } from '@devvit/public-api';
+ });
- const response = await media.upload({
- url: 'https://media2.giphy.com/media/xTiN0CNHgoRf1Ha7CM/giphy.gif',
- type: 'gif',
+await reddit.submitPost({
+ subredditName: 'my_subreddit',
+ title: 'Post with uploaded media',
+ richtext,
+});
+```
+
+### Example: submit a comment with uploaded media using RichTextBuilder
+```ts title="server/index.ts"
+import { media } from '@devvit/web/server';
+import { reddit, RichTextBuilder } from '@devvit/reddit';
+
+// Parent can be a post id (t3_...) or comment id (t1_...)
+const parentId = 't3_abc123';
+
+const uploaded = await media.upload({
+ url: 'https://example.com/reply-image.png',
+ type: 'image',
+});
+
+const commentRichtext = new RichTextBuilder()
+ .paragraph((p) => {
+ p.text({ text: 'Here is the image:' });
+ })
+ .paragraph((p) => {
+ p.image({ mediaUrl: uploaded.mediaUrl });
});
- ```
-
-
+
+await reddit.submitComment({
+ id: parentId,
+ richtext: commentRichtext,
+});
+```
+
+### Example: raw RTJSON (without RichTextBuilder)
+If you prefer raw RTJSON, pass an object directly to `richtext`:
+
+```ts title="server/index.ts"
+import { media } from '@devvit/web/server';
+import { reddit } from '@devvit/reddit';
+
+const uploaded = await media.upload({
+ url: 'https://example.com/raw-rtjson.png',
+ type: 'image',
+});
+
+await reddit.submitComment({
+ id: 't3_abc123',
+ richtext: {
+ document: [
+ {
+ e: 'par',
+ c: [{ e: 'text', t: 'Raw RTJSON image:' }],
+ },
+ {
+ e: 'par',
+ c: [{ e: 'img', mediaUrl: uploaded.mediaUrl, c: 'RTJSON image node' }],
+ },
+ ],
+ },
+});
+```
## Canvas screenshots
@@ -68,25 +185,22 @@ const response = await fetch('/api/upload-screenshot', {
```
```ts title="server/index.ts"
-import { media } from '@devvit/media';
+import { media } from '@devvit/web/server';
app.post('/api/upload-screenshot', async (c) => {
const { image } = await c.req.json();
const response = await media.upload({
- url: image, // data URL from canvas
- type: 'png',
+ url: image, // data URL from canvas
+ type: 'image',
});
return c.json({ url: response.mediaUrl });
});
```
-## Limitations
-
-- The formats supported are PNG, JPEG, WEBP, and GIF.
-- The maximum file size allowed is 20 MB.
-
-### Notes
+## Notes and limits
-- When uploading a WEBP image, it will be converted to JPEG. As such, the Reddit URL returned points to a JPEG image.
+- Supported image upload formats: PNG, JPEG, WEBP, and GIF.
+- Maximum upload size: 20 MB.
+- WEBP uploads may be converted to JPEG in the returned Reddit URL.
diff --git a/versioned_docs/version-0.12/capabilities/server/media-uploads.mdx b/versioned_docs/version-0.12/capabilities/server/media-uploads.mdx
index 7316f1a7..eda4b7d1 100644
--- a/versioned_docs/version-0.12/capabilities/server/media-uploads.mdx
+++ b/versioned_docs/version-0.12/capabilities/server/media-uploads.mdx
@@ -1,15 +1,12 @@
-import Tabs from '@theme/Tabs';
-import TabItem from '@theme/TabItem';
-
# Media Uploads
:::warning
-Apps can only display images hosted on Reddit
+Apps can only display media hosted on Reddit
:::
-You can upload images to Reddit at runtime using the `media` capability. This is different than static images, which are part of your [assets](../blocks/app_image_assets.md).
+You can upload media to Reddit at runtime using the `media` capability. This is different than static images, which are part of your [assets](../blocks/app_image_assets.md).
-Runtime images are useful for embedding images in RTJSON (Posts and Comments) as well as displaying them within an interactive post app.
+Runtime media is useful for embedding media in RTJSON (Posts and Comments) as well as displaying it within an interactive post app.
## Enabling media uploads
Enable the `media` permission in your `devvit.json` file.
@@ -21,32 +18,152 @@ Enable the `media` permission in your `devvit.json` file.
}
```
-## Using media uploads
-On the server, you can pass the URL of any remotely hosted image (even if its not hosted on Reddit) to the `media.upload` function. This function will return a Reddit URL. Both HTTP and data URLs are supported.
-
-
-
- ```ts title="server/index.ts"
- import { media } from '@devvit/media';
- function submitImage() {
- const response = await media.upload({
- url: 'https://media2.giphy.com/media/xTiN0CNHgoRf1Ha7CM/giphy.gif',
- type: 'gif',
+## Media uploads (Devvit Web)
+On the server, pass a remote URL or data URL to `media.upload()` to upload an image, GIF, or video and get a Reddit-hosted asset you can safely render in posts, comments, and rich text.
+
+### Response type
+`media.upload()` returns:
+
+```ts
+type MediaAsset = {
+ mediaId: string;
+ mediaUrl: string;
+};
+```
+
+- `mediaId`: Reddit media asset ID.
+- `mediaUrl`: Reddit CDN URL (use this in rich text or UI).
+
+### `media.upload()` input
+`media.upload()` expects an object with:
+
+- `url`: The media URL (remote URL or data URL).
+- `type`: The media kind (`'image'`, `'gif'`, or `'video'`).
+
+```ts
+type UploadMediaOptions = {
+ url: string; // remote URL or data URL
+ type: 'image' | 'gif' | 'video';
+};
+```
+
+Use `type: 'image'` for PNG, JPEG, and WEBP uploads.
+
+### Basic server usage
+```ts title="server/index.ts"
+import { media } from '@devvit/web/server';
+
+const uploaded = await media.upload({
+ url: 'https://example.com/my-image.png',
+ type: 'image',
+});
+
+// uploaded.mediaId
+// uploaded.mediaUrl
+```
+
+### Example: API endpoint returning upload response
+```ts title="server/index.ts"
+import { media } from '@devvit/web/server';
+
+app.post('/api/upload', async (c) => {
+ const { url, type } = await c.req.json<{
+ url: string;
+ type: 'image' | 'gif' | 'video';
+ }>();
+
+ const uploaded = await media.upload({ url, type });
+
+ return c.json({
+ mediaId: uploaded.mediaId,
+ mediaUrl: uploaded.mediaUrl,
+ });
+});
+```
+
+### Example: submit a post with uploaded media using RichTextBuilder
+```ts title="server/index.ts"
+import { media } from '@devvit/web/server';
+import { reddit, RichTextBuilder } from '@devvit/reddit';
+
+const uploaded = await media.upload({
+ url: 'https://example.com/cover.png',
+ type: 'image',
+});
+
+const richtext = new RichTextBuilder()
+ .paragraph((p) => {
+ p.text({ text: 'Uploaded image:' });
+ })
+ .paragraph((p) => {
+ p.image({
+ mediaUrl: uploaded.mediaUrl,
+ caption: 'Rendered from media.upload()',
});
- }
- ```
-
-
- ```ts
- import { Devvit } from '@devvit/public-api';
+ });
- const response = await media.upload({
- url: 'https://media2.giphy.com/media/xTiN0CNHgoRf1Ha7CM/giphy.gif',
- type: 'gif',
+await reddit.submitPost({
+ subredditName: 'my_subreddit',
+ title: 'Post with uploaded media',
+ richtext,
+});
+```
+
+### Example: submit a comment with uploaded media using RichTextBuilder
+```ts title="server/index.ts"
+import { media } from '@devvit/web/server';
+import { reddit, RichTextBuilder } from '@devvit/reddit';
+
+// Parent can be a post id (t3_...) or comment id (t1_...)
+const parentId = 't3_abc123';
+
+const uploaded = await media.upload({
+ url: 'https://example.com/reply-image.png',
+ type: 'image',
+});
+
+const commentRichtext = new RichTextBuilder()
+ .paragraph((p) => {
+ p.text({ text: 'Here is the image:' });
+ })
+ .paragraph((p) => {
+ p.image({ mediaUrl: uploaded.mediaUrl });
});
- ```
-
-
+
+await reddit.submitComment({
+ id: parentId,
+ richtext: commentRichtext,
+});
+```
+
+### Example: raw RTJSON (without RichTextBuilder)
+If you prefer raw RTJSON, pass an object directly to `richtext`:
+
+```ts title="server/index.ts"
+import { media } from '@devvit/web/server';
+import { reddit } from '@devvit/reddit';
+
+const uploaded = await media.upload({
+ url: 'https://example.com/raw-rtjson.png',
+ type: 'image',
+});
+
+await reddit.submitComment({
+ id: 't3_abc123',
+ richtext: {
+ document: [
+ {
+ e: 'par',
+ c: [{ e: 'text', t: 'Raw RTJSON image:' }],
+ },
+ {
+ e: 'par',
+ c: [{ e: 'img', mediaUrl: uploaded.mediaUrl, c: 'RTJSON image node' }],
+ },
+ ],
+ },
+});
+```
## Canvas screenshots
@@ -68,25 +185,22 @@ const response = await fetch('/api/upload-screenshot', {
```
```ts title="server/index.ts"
-import { media } from '@devvit/media';
+import { media } from '@devvit/web/server';
app.post('/api/upload-screenshot', async (c) => {
const { image } = await c.req.json();
const response = await media.upload({
- url: image, // data URL from canvas
- type: 'png',
+ url: image, // data URL from canvas
+ type: 'image',
});
return c.json({ url: response.mediaUrl });
});
```
-## Limitations
-
-- The formats supported are PNG, JPEG, WEBP, and GIF.
-- The maximum file size allowed is 20 MB.
-
-### Notes
+## Notes and limits
-- When uploading a WEBP image, it will be converted to JPEG. As such, the Reddit URL returned points to a JPEG image.
+- Supported image upload formats: PNG, JPEG, WEBP, and GIF.
+- Maximum upload size: 20 MB.
+- WEBP uploads may be converted to JPEG in the returned Reddit URL.