Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/capabilities/client/menu-actions.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ You can decide where the menu action shows up by specifying the location propert
| ---------------------- | ------------------------------ | ------------------------------------------------------------------------------- |
| location (required) | `comment`, `post`, `subreddit` | Determines where the menu action appears. |
| postFilter (optional) | `currentApp` | Shows the action created by your app. The default is no filtering. |
| forUserType (optional) | `moderator` | Specifies the user types that can see the menu action. The default is everyone. |
| forUserType (optional) | `moderator`, `user` | Specifies the user types that can see the menu action. The default is `moderator`. |

:::note
For moderator permission security, when opening a form from a menu action with `forUserType: moderator`, the user initiating the action must complete all actions within 10 minutes.
Expand Down
4 changes: 3 additions & 1 deletion docs/capabilities/creating_custom_post.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Creating a Custom Post

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.
Redditors interact with your app through custom posts. To create a custom post, define the entry points in `devvit.json`, then use `submitCustomPost` to create a post that references one of those entry points.

## **How it Works**

Expand Down Expand Up @@ -46,6 +46,8 @@ export const createPost = async () => {
| `userGeneratedContent` | [Enables user-generated content](../capabilities/server/userActions) |
| `styles` | Controls post appearance in the Reddit UI. See [Custom Post Styles](#custom-post-styles) |

You do not need to provide a separate `preview` element when creating a custom post with Devvit Web.

## **Custom Post Styles**

Custom post styles let you control how a custom post looks in the Reddit UI, separate from the content inside your webview. You can:
Expand Down
41 changes: 37 additions & 4 deletions docs/capabilities/devvit-web/devvit_web_configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ Additionally, you must include at least one of:

## Configuration sections

### Endpoint conventions

- Use `/api/` for client-facing endpoints that your webview calls with `fetch()`.
- Use `/internal/` for handlers declared in `devvit.json`, such as menu actions, forms, triggers, scheduler tasks, settings validation, and payments endpoints.

### Core properties

| Property | Type | Description | Required |
Expand All @@ -46,6 +51,7 @@ Additionally, you must include at least one of:
| Property | Type | Description | Required |
| ----------------- | ------ | ------------------------------ | -------- |
| `permissions` | object | What your app is allowed to do | No |
| `settings` | object | Global and subreddit settings | No |
| `media` | object | Static asset configuration | No |
| `marketingAssets` | object | Assets for featuring your app | No |

Expand Down Expand Up @@ -258,12 +264,39 @@ Map form identifiers to submission endpoints:
```json
{
"forms": {
"contact_form": "/internal/forms/contact",
"feedback_form": "/internal/forms/feedback"
"contact_form": "/internal/form/contact",
"feedback_form": "/internal/form/feedback"
}
}
```

### Settings configuration

Define settings that can be managed globally by developers or per-installation by moderators:

```json
{
"settings": {
"global": {
"apiKey": {
"type": "string",
"label": "API Key",
"isSecret": true
}
},
"subreddit": {
"mopEnabled": {
"type": "boolean",
"label": "Enable Comment Mop",
"defaultValue": true
}
}
}
}
```

See [Settings and Secrets](../server/settings-and-secrets.mdx) for the full settings schema, supported field types, and validation endpoints.

### Marketing assets

Configure app presentation:
Expand Down Expand Up @@ -296,7 +329,7 @@ Configure build commands run by the Devvit CLI. These commands run relative to t
**Properties:**

- `dev` (string): Command run by `devvit playtest` to build or watch your client/server artifacts
- `build` (string): Command run by `devvit upload` to build your client/server artifacts
- `build` (string): Command run when Devvit needs a production build, such as `devvit upload` or `devvit publish`

### Development configuration

Expand Down Expand Up @@ -331,7 +364,7 @@ The `devvit.json` configuration is validated against the JSON Schema at build ti
1. **Always include the `$schema` property** for IDE autocompletion and validation.
2. **Use specific permission scopes.** Only request permissions your app actually uses.
3. **Set appropriate menu scopes.** Consider whether features should be available to all users or just moderators.
4. **Validate endpoints.** Ensure all internal endpoints start with `/internal/`.
4. **Validate endpoints.** Use `/api/` for client-facing fetch routes and `/internal/` for `devvit.json` handlers.
5. **Use meaningful names.** Choose descriptive names for entrypoints, tasks, and forms.
6. **Test configurations.** Validate your config with `devvit build` before deployment.

Expand Down
10 changes: 6 additions & 4 deletions docs/capabilities/devvit-web/devvit_web_overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ Devvit Web allows developers to build Devvit apps just like you would for the we
- **Server endpoints** that you define to communicate between the webview client and the Devvit server, using industry-standard frameworks and technologies (like Express.js, Hono, Koa, etc.).
- **Devvit configuration** with a traditional client/server split. Devvit capabilities are now in one of three places:
- A configuration file in devvit.json for defining app metadata, permissions, and capabilities
- Client capabilities in the @devvit/client SDK
- Server capabilities, like Redis and Reddit API with the @devvit/server SDK
- Client capabilities in the `@devvit/web/client` SDK
- Server capabilities, like Redis and Reddit API, in the `@devvit/web/server` SDK

With Devvit Web, you have continued access to our hosting services, key capabilities like Redis and Reddit API, standard web technologies, and a typical client/server pattern to build your apps.

Expand Down Expand Up @@ -81,7 +81,9 @@ This folder includes server-side code. We provide a node server, and you can use
We also provide an authentication middleware so you don’t have to worry about authentication.

:::note
All server endpoints must start with `/api/` (e.g. `/api/get-something` or `/api/widgets/42`).
Use `/api/` for client-facing endpoints that your webview calls with `fetch()`.

Use `/internal/` for Devvit-managed handlers declared in `devvit.json`, such as menu actions, forms, triggers, scheduler tasks, settings validation, and payments endpoints.
:::

<img
Expand All @@ -92,6 +94,6 @@ All server endpoints must start with `/api/` (e.g. `/api/get-something` or `/api

### Configuration in `devvit.json`

`devvit.json` is the configuration file for Devvit apps. It defines an app's post configuration, Node.js server configuration, permissions, scheduled jobs, event triggers, menu entries, payments configuration, and project settings. `devvit.json` replaces the legacy `devvit.yaml` configuration. A project should have one or the other but not both.
`devvit.json` is the configuration file for Devvit apps. It defines an app's post configuration, Node.js server configuration, permissions, scheduled jobs, event triggers, menu entries, payments configuration, and project settings.

Learn more about [devvit.json](./devvit_web_configuration.md)
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ For larger amounts of data, you should use [Redis](../server/redis). Learn more
Enable your app to perform actions on behalf of users (with their permission):

- Create posts or comments as the user
- Subscribe users to subreddits (coming soon)
- Subscribe users to subreddits after manual Reddit approval

Learn more about [User Actions](../server/userActions)

Expand Down Expand Up @@ -114,5 +114,10 @@ const post = await reddit.submitCustomPost({
// Later, update post data when someone wins
const updatedPost = await reddit.getPostById(post.id); await updatedPost.setPostData({ ...context.postData, gameState: 'completed', winner: currentUsername, totalGuesses: context.postData.totalGuesses + 1 });

// Create a comment as the user announcing their win await reddit.submitComment({ runAs: 'USER', id: post.id, text: 🎉 ${currentUsername} won the game! });
// Create a comment as the user announcing their win
await reddit.submitComment({
runAs: 'USER',
id: post.id,
text: `🎉 ${currentUsername} won the game!`,
});
```
2 changes: 1 addition & 1 deletion docs/capabilities/server/http-fetch-policy.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ When requesting domains to be allow-listed, they fall into three categories:
- `spacetimedb.com`
- `s3.amazonaws.com`
- `storage.googleapis.com`
- Demonstrate a capability that `@devvit/server` doesn't support
- Demonstrate a capability that `@devvit/web/server` doesn't support
- Valid use cases include:
- Asset hosting (videos, images, music)
- Relational databases
Expand Down
4 changes: 2 additions & 2 deletions docs/capabilities/server/http-fetch.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ Client-side fetch has different restrictions and can only make requests to your
**Client-side restrictions:**

- **Domain limitation**: Can only make requests to your own webview domain
- **Endpoint requirement**: All requests must target endpoints that end with `/api`
- **Endpoint requirement**: All requests must target your own `/api/...` endpoints
- **Authentication**: Handled automatically - no need to manage auth tokens
- **No external domains**: Cannot make requests to external domains from client-side code

Expand All @@ -91,7 +91,7 @@ const handleFetchData = async () => {
// Incorrect: cannot fetch external domains from client-side
// const response = await fetch('https://external-api.com/data');

// Incorrect: endpoint must end with /api
// Incorrect: client-side fetches should target your own /api/... endpoints
// const response = await fetch('/user-data');
```

Expand Down
2 changes: 1 addition & 1 deletion docs/capabilities/server/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Allows you to build apps where the end user can upload custom images to Reddit's

## [Reddit API](./reddit-api.mdx)

Allows you to query information from Reddit such as comments, posts and upvotes. Limited to installation scope of the application.
Allows you to query information from Reddit such as comments, posts, moderation state, and other community data. Limited to the installation scope of the application.

## [Data storage (Redis)](./redis.mdx)

Expand Down
7 changes: 3 additions & 4 deletions docs/capabilities/server/reddit-api.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Reddit API Overview

The Reddit API allows you to read and write Reddit content such as posts / comments / upvotes, in order to integrate your app's behavior with the content of the community it's installed in.
The Reddit API allows you to read and write Reddit content such as posts, comments, and moderation actions so your app can integrate with the community where it is installed.

:::note
Unlike traditional Reddit API usage, you don't need to create an app at [reddit.com/prefs/apps](https://www.reddit.com/prefs/apps) or manage API keys. Devvit handles authentication automatically when you enable the `reddit` permission in your app.
Expand Down Expand Up @@ -30,7 +30,7 @@ Here's how to obtain a reference to the Reddit client
```

```ts title="server/index.ts"
import { reddit } from '@devvit/reddit';
import { reddit } from '@devvit/web/server';
```

## Reddit Thing IDs
Expand Down Expand Up @@ -62,7 +62,6 @@ const parentId = comment.parentId; // 't3_abc123' or 't1_def456'

### Submitting a post
```ts
import { Devvit } from '@devvit/public-api';
import { context, reddit } from '@devvit/web/server';

export const createPost = async () => {
Expand Down Expand Up @@ -99,7 +98,7 @@ export const createComment = async () => {
}

reddit.submitComment({
postId: 't3_123456', // Replace with the actual post ID
id: 't3_123456', // Replace with the actual post or comment ID
text: 'This is a comment from a Devvit app',
runAs: 'USER' // Optional: specify the user to run as
});
Expand Down
4 changes: 2 additions & 2 deletions docs/capabilities/server/triggers.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@ Event triggers let your app automatically respond to a user's or moderator's act
- `onPostSpoilerUpdate`
- `onAppInstall`
- `onAppUpgrade`
- `onModActions`
- `onModAction`
- `onModMail`
- `onAutomoderatorFilterPost`
- `onAutomoderatorFilterComment`

A full list of events and their payloads can be found in the [EventTypes documentation](../../api/public-api/@devvit/namespaces/EventTypes/). For more details on Mod specific actions, see [ModActions](../../api/redditapi/models/interfaces/ModAction) and [ModMail](../../api/public-api/type-aliases/ModMailDefinition).
A full list of events and their payloads can be found in the [EventTypes documentation](../../api/public-api/@devvit/namespaces/EventTypes/). In `devvit.json`, use the trigger key `onModAction`; the underlying trigger event type is documented as `ModAction`. For more details on mod-specific actions, see [ModActions](../../api/redditapi/models/interfaces/ModAction) and [ModMail](../../api/public-api/type-aliases/ModMailDefinition).

## Setting up triggers

Expand Down
14 changes: 7 additions & 7 deletions docs/capabilities/server/userActions.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import TabItem from '@theme/TabItem';

# User Actions

User actions allow your app to submit posts, submit comments, and subscribe to the current subreddit on behalf of the logged in user. These actions occur on the logged in user's account instead of the app account. This enables stronger user engagement while ensuring user control and transparency.
User actions allow your app to submit posts, submit comments, and, with manual Reddit approval, subscribe to the current subreddit on behalf of the logged in user. These actions occur on the logged in user's account instead of the app account. This enables stronger user engagement while ensuring user control and transparency.

---

Expand All @@ -12,7 +12,7 @@ User actions allow your app to submit posts, submit comments, and subscribe to t
By default, apps make posts or comments using their associated app account. With user actions enabled, your app can:

- Create posts or comments on behalf of the user (from the post UI, a form, or a menu action)
- Subscribe the user to the current subreddit
- Subscribe the user to the current subreddit after manual Reddit approval

Some actions are not available to apps to prevent abuse and maintain platform integrity:

Expand Down Expand Up @@ -73,7 +73,7 @@ To enable user actions, add the required permissions to your `devvit.json`:
After enabling, you can call certain Reddit APIs on behalf of the user by passing the option `runAs: 'USER'`. The following APIs support this option:

- [submitPost()](../../api/redditapi/RedditAPIClient/classes/RedditAPIClient.md#submitpost)
- [submitCustomPost()](../../api/redditapi/RedditAPIClient/classes/RedditAPIClient.md)
- [submitCustomPost()](../../api/redditapi/RedditAPIClient/classes/RedditAPIClient.md#submitcustompost)
- [submitComment()](../../api/redditapi/RedditAPIClient/classes/RedditAPIClient.md#submitcomment)

If `runAs` is not specified, the API will use `runAs: 'APP'` by default.
Expand Down Expand Up @@ -110,7 +110,7 @@ Your app version needs to be approved in order for user actions to be enabled fo
<TabItem value="hono">

```tsx title="server/index.ts"
import { reddit } from '@devvit/web/server';
import { context, reddit } from '@devvit/web/server';

// ...

Expand Down Expand Up @@ -138,7 +138,7 @@ app.post('/internal/post-create', async (c) => {
<TabItem value="express">

```tsx title="server/index.ts"
import { reddit } from '@devvit/web/server';
import { context, reddit } from '@devvit/web/server';

// ...

Expand Down Expand Up @@ -170,7 +170,7 @@ router.post('/internal/post-create', async (_req, res) => {

## Example: Subscribe to current subreddit

The [subscribeToCurrentSubreddit()](../../api/redditapi/RedditAPIClient/classes/RedditAPIClient.md#subscribetocurrentsubreddit) API does not take a `runAs` parameter; it subscribes as the user by default (if specified in `devvit.json` and approved).
The [subscribeToCurrentSubreddit()](../../api/redditapi/RedditAPIClient/classes/RedditAPIClient.md#subscribetocurrentsubreddit) API does not take a `runAs` parameter. This API still requires manual approval from Reddit before it can subscribe on behalf of the user.

<Tabs
variant="pill"
Expand Down Expand Up @@ -248,4 +248,4 @@ This example mixes intention and is confusing for the user. Apps like this that

This avoids surprising the user, enables a reporting flow, and allows the user to easily delete their score comment. Replying to a stickied comment keeps this repetitive content with low discussion value out of the way, in an area that needs to be expanded to view.

If offering a way for the user to add a custom message to their score, the comment can be posted as a top-level comment. This prioritizes human discussion and creates a more engaging comment section.
If offering a way for the user to add a custom message to their score, the comment can be posted as a top-level comment. This prioritizes human discussion and creates a more engaging comment section.
4 changes: 2 additions & 2 deletions docs/earn-money/payments/payments_test.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ Use the payments sandbox environment to simulate payment transactions. All apps

To test your app:

1. Run `devvit upload` to upload your app to the Apps directory.
2. Run `devvit playtest` <test-subreddit-name> .
1. Run `devvit playtest <test-subreddit-name>`.
2. If your app does not already have a playtest subreddit, Devvit will automatically create one for you.

Once you start a playtest session, a new pre-release version of your app is automatically created and installed on your test subreddit. The pre-release version has a fourth decimal place, so if your current app is 0.0.1, the first pre-release version will be 0.0.1.1.

Expand Down
10 changes: 9 additions & 1 deletion docs/examples/tutorials/mod-tool.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,12 @@
slug: /examples/tutorials/mod-tool
---

# Build a Mod Tool - Three Strikes
# Build a Mod Tool

If you're building a new moderator workflow today, start with:

- [Quickstart for Mod Tools](../../quickstart/quickstart-mod-tool.md)
- [Template library](../template-library.md)
- [Mod Resources](../../guides/best-practices/mod_resources.md)

The current mod-tool quickstart walks through building Comment Mop, a moderator-only menu action that removes or locks a full comment tree.
Loading
Loading