|
| 1 | +# Creating a Custom Post |
| 2 | + |
| 3 | +Redditors interact with your app through custom posts. To create a custom post, you’ll define the entry points in `devvit.json,` then use `submitCustomPost` to create a post that references one of those entry points. |
| 4 | + |
| 5 | +## **How it Works** |
| 6 | + |
| 7 | +Each key in the `entrypoints` object (e.g. "default", "game") maps to an HTML file in your build output. When you call `submitCustomPost`, the entry parameter references one of these keys. |
| 8 | + |
| 9 | +``` |
| 10 | +// devvit.json default template |
| 11 | +... |
| 12 | +"name": "test-custom-post", |
| 13 | + "post": { |
| 14 | + "dir": "dist/client", |
| 15 | + "entrypoints": { |
| 16 | + "default": { |
| 17 | + "entry": "splash.html" |
| 18 | + }, |
| 19 | + "game": { |
| 20 | + "entry": "game.html" |
| 21 | + } |
| 22 | + } |
| 23 | + } |
| 24 | +... |
| 25 | +``` |
| 26 | + |
| 27 | +```ts |
| 28 | +import { reddit } from '@devvit/web/server'; |
| 29 | + |
| 30 | +export const createPost = async () => { |
| 31 | + return await reddit.submitCustomPost({ |
| 32 | + title: 'Example title for post', |
| 33 | + entry: 'default' // default |
| 34 | + }); |
| 35 | +}; |
| 36 | + |
| 37 | +``` |
| 38 | + |
| 39 | +`submitCustomPost` accepts the following optional parameters: |
| 40 | + |
| 41 | +| Parameter | Description | |
| 42 | +| :---- | :---- | |
| 43 | +| `entry` | Key of the entrypoint defined in `devvit.json` | |
| 44 | +| `postData` | [Updates post data after creation](../capabilities/server/post-data) | |
| 45 | +| `textFallback` | [Specifies alternative text content](../capabilities/server/text_fallback) | |
| 46 | +| `userGeneratedContent` | [Enables user-generated content](..capabilities/server/userActions) | |
| 47 | +| `styles` | Controls post appearance in the Reddit UI. See [Custom Post Styles](#custom-post-styles) | |
| 48 | + |
| 49 | +## **Custom Post Styles** |
| 50 | + |
| 51 | +Custom post styles let you control how a custom post looks in the Reddit UI, separate from the content inside your webview. You can: |
| 52 | + |
| 53 | +* Set the **light mode or dark mode background color** shown while the iframe loads |
| 54 | +* Choose the **post height** (for example, `“REGULAR”` or `“TALL”`) to control how much vertical space the post takes in the feed. |
| 55 | +* Provide a **share image URL** that’s used for link previews when the post is shared outside Reddit. |
| 56 | + |
| 57 | +All style fields are optional. If you don’t set them, Reddit’s default settings apply. |
| 58 | + |
| 59 | +### Properties |
| 60 | + |
| 61 | +| Field | Type | Description | |
| 62 | +| :---- | :---- | :---- | |
| 63 | +| `backgroundColor` | `string` (optional) | The **default background color** shown before the iframe content loads. Must be in **`#RRGGBBAA`** format (red, green, blue, alpha transparency). The value is **case-insensitive**. Defaults to **transparent** (`#00000000`). | |
| 64 | +| `backgroundColorDark` | `string` (optional) | The **dark mode background color** shown before the iframe content loads. Must be in **`#RRGGBBAA`** format with a leading `#`. Defaults to **transparent** (`#00000000`). | |
| 65 | +| `height` | `EntrypointHeight` enum (optional) | Post height. `TALL` \= 512px, `REGULAR` \= 320px. Width varies from \~288–880px depending on device and viewport. Defaults to `”TALL”`. | |
| 66 | +| `shareImageUrl` | `string` (optional) | The **preview image URL** used when the post is shared externally (for example, OpenGraph `og:image`). Note: The image **must** be hosted on [i.redd.it](http://i.redd.it) domain. Use the [media upload plugin](https://developers.reddit.com/docs/capabilities/server/media-uploads) to upload a custom image. This only works if your app is on a public subreddit. Defaults to Reddit’s generic share image: `https://i.redd.it/o0h58lzmax6a1.png`. | |
| 67 | + |
| 68 | +### Creating a custom post with styles |
| 69 | + |
| 70 | +Set your custom post styles when you create a custom post: |
| 71 | + |
| 72 | +```javascript |
| 73 | +await reddit.submitCustomPost({ |
| 74 | + "title": "Post with styles title", |
| 75 | + "styles": { |
| 76 | + "backgroundColor": "#FFFFFFFF", // white, fully opaque |
| 77 | + "backgroundColorDark": "#000000FF", // black, fully opaque |
| 78 | + "height": "TALL", |
| 79 | + "shareImageUrl": "https://reddi.it/12345.png" |
| 80 | + } |
| 81 | +}) |
| 82 | +``` |
| 83 | + |
| 84 | +Note: All style fields are optional. |
| 85 | + |
| 86 | +### Updating styles |
| 87 | + |
| 88 | +Use `post.setCustomPostStyles()` to update styles on an existing post. Only include the fields you want to change. Omitted fields remain unchanged. |
| 89 | + |
| 90 | +```javascript |
| 91 | +const post = await reddit.getPostById(context.postId); |
| 92 | +await post.setCustomPostStyles({ |
| 93 | + "styles": { |
| 94 | + "shareImageUrl": "https://example.com/new-preview.png" |
| 95 | + } |
| 96 | +}); |
| 97 | +``` |
| 98 | + |
| 99 | +Existing `background_color`, `background_color_dark`, and `height` values remain unchanged. |
| 100 | + |
| 101 | +### Reading styles |
| 102 | + |
| 103 | +Use `post.getCustomPostStyles()` or `reddit.getPostStyles(id)` to read the styles on an existing post. Settings that haven’t been set yet will give you their default values. |
| 104 | + |
| 105 | +```javascript |
| 106 | +const post = await reddit.getPostById(context.postId); |
| 107 | +const styles = await post.getCustomPostStyles(); |
| 108 | +// Or, if you don't need the post object and want just the styles: |
| 109 | +const styles = await reddit.getPostStyles(context.postId); |
| 110 | +``` |
| 111 | + |
| 112 | +# Best Practices |
| 113 | + |
| 114 | +* **Color format:** Always provide 8-digit hex with alpha: `#RRGGBBAA`. |
| 115 | + * `RR`, `GG`, `BB`: 00–FF (0–255) color channels. |
| 116 | + * `AA`: 00–FF alpha channel (`00` \= fully transparent, `FF` \= fully opaque). |
| 117 | + |
| 118 | +* **Transparency:** Use alpha (`AA`) to blend your app experience smoothly with Reddit backgrounds (for example, `#00000080` for semi-transparent black). |
| 119 | + |
| 120 | +* **Dark mode:** Always set `background_color_dark` when your iframe content has a dark theme so the pre-load state matches the final experience. |
| 121 | + |
| 122 | +* **Height:** Choose the `height` that best matches your UI. The platform will handle mapping that logical value to the correct pixel height for the client. |
| 123 | + |
| 124 | +* **Share image:** Must be hosted on [i.redd.it](http://i.redd.it) (use the [media upload plugin](https://developers.reddit.com/docs/capabilities/server/media-uploads)) and ensure the asset meets typical OpenGraph sizing and aspect-ratio expectations so it renders cleanly across platforms. This only works if your app is on a public subreddit. |
0 commit comments