diff --git a/docs/capabilities/client/menu-actions.mdx b/docs/capabilities/client/menu-actions.mdx
index 348944e8..278e4bd2 100644
--- a/docs/capabilities/client/menu-actions.mdx
+++ b/docs/capabilities/client/menu-actions.mdx
@@ -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.
diff --git a/docs/capabilities/creating_custom_post.md b/docs/capabilities/creating_custom_post.md
index 66ef675b..3a996538 100644
--- a/docs/capabilities/creating_custom_post.md
+++ b/docs/capabilities/creating_custom_post.md
@@ -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**
@@ -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:
diff --git a/docs/capabilities/devvit-web/devvit_web_configuration.md b/docs/capabilities/devvit-web/devvit_web_configuration.md
index 57d71804..9e5337a5 100644
--- a/docs/capabilities/devvit-web/devvit_web_configuration.md
+++ b/docs/capabilities/devvit-web/devvit_web_configuration.md
@@ -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 |
@@ -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 |
@@ -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:
@@ -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
@@ -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.
diff --git a/docs/capabilities/devvit-web/devvit_web_overview.mdx b/docs/capabilities/devvit-web/devvit_web_overview.mdx
index b208d4e6..2725579a 100644
--- a/docs/capabilities/devvit-web/devvit_web_overview.mdx
+++ b/docs/capabilities/devvit-web/devvit_web_overview.mdx
@@ -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.
@@ -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.
:::
{
// 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');
```
diff --git a/docs/capabilities/server/overview.md b/docs/capabilities/server/overview.md
index fdd17182..5968cd49 100644
--- a/docs/capabilities/server/overview.md
+++ b/docs/capabilities/server/overview.md
@@ -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)
diff --git a/docs/capabilities/server/reddit-api.mdx b/docs/capabilities/server/reddit-api.mdx
index a2b32781..fc867ccd 100644
--- a/docs/capabilities/server/reddit-api.mdx
+++ b/docs/capabilities/server/reddit-api.mdx
@@ -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.
@@ -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
@@ -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 () => {
@@ -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
});
diff --git a/docs/capabilities/server/triggers.mdx b/docs/capabilities/server/triggers.mdx
index 409a6d18..3f7d5671 100644
--- a/docs/capabilities/server/triggers.mdx
+++ b/docs/capabilities/server/triggers.mdx
@@ -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
diff --git a/docs/capabilities/server/userActions.mdx b/docs/capabilities/server/userActions.mdx
index 580e2818..9fcdd529 100644
--- a/docs/capabilities/server/userActions.mdx
+++ b/docs/capabilities/server/userActions.mdx
@@ -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.
---
@@ -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:
@@ -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.
@@ -110,7 +110,7 @@ Your app version needs to be approved in order for user actions to be enabled fo
```tsx title="server/index.ts"
-import { reddit } from '@devvit/web/server';
+import { context, reddit } from '@devvit/web/server';
// ...
@@ -138,7 +138,7 @@ app.post('/internal/post-create', async (c) => {
```tsx title="server/index.ts"
-import { reddit } from '@devvit/web/server';
+import { context, reddit } from '@devvit/web/server';
// ...
@@ -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.
.
+1. Run `devvit playtest `.
+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.
diff --git a/docs/examples/tutorials/mod-tool.md b/docs/examples/tutorials/mod-tool.md
index 63ad5dc3..f8372609 100644
--- a/docs/examples/tutorials/mod-tool.md
+++ b/docs/examples/tutorials/mod-tool.md
@@ -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.
diff --git a/docs/guides/faq.mdx b/docs/guides/faq.mdx
index bacc0cd9..1d46bd51 100644
--- a/docs/guides/faq.mdx
+++ b/docs/guides/faq.mdx
@@ -26,6 +26,8 @@ If you are building an external script, bot, or website outside Devvit, that is
The fastest path is the [App quickstart](../quickstart/quickstart.md), which walks you through creating a project, connecting your Reddit account, and starting a playtest environment.
+If you already know you are building a moderator workflow, start with [Quickstart for Mod Tools](../quickstart/quickstart-mod-tool.md) instead of the general app quickstart.
+
If you already know which kind of app you want to build, you can also start with:
- [Quickstart for Games](../quickstart/quickstart.md)
@@ -67,6 +69,8 @@ Not completely. Devvit apps run against Reddit, so the normal development flow u
The quickstart uses `npm run dev`, which starts a Devvit playtest session for you. If you need more control over that flow, see [Playtest](./tools/playtest.md).
+You do not need to run `upload` before starting a normal playtest session.
+
If you are wondering why a purely local setup is not enough, the quickstart calls this out directly: backend calls do not work when you test the app only locally.
@@ -181,11 +185,11 @@ For current Devvit Web apps, customize the first screen through your `post.entry
-
+
-Should I use the legacy splash field or HTML launch entry points?
+Should I use splash or HTML launch entry points?
-Prefer HTML launch entry points for new work. The older `splash` parameter is still documented, but the migration guide marks it as deprecated in favor of entrypoint-based launch screens and `entry` selection in `submitCustomPost()`. If you are updating an older app or wondering why splash changes are confusing, start with [Migrating from Splash Screens](../capabilities/server/launch_screen_and_entry_points/splash_migration.mdx).
+Use HTML launch entry points. Configure launch screens through your `post.entrypoints` in `devvit.json` and `entry` selection in `submitCustomPost()`. The main references are [Launch overview](../capabilities/server/launch_screen_and_entry_points/launch_overview.mdx), [View modes and entry points](../capabilities/server/launch_screen_and_entry_points/view_modes_entry_points.md), and [Launch screen customization](../capabilities/server/launch_screen_and_entry_points/launch_screen_customization.md).
diff --git a/docs/guides/tools/devvit_cli.mdx b/docs/guides/tools/devvit_cli.mdx
index fe985951..4f8baf94 100644
--- a/docs/guides/tools/devvit_cli.mdx
+++ b/docs/guides/tools/devvit_cli.mdx
@@ -248,6 +248,8 @@ $ npx devvit new --here
Installs your app to your test subreddit and starts a playtest session. A new version of your app is installed whenever you save changes to your app code, and logs are continuously streamed. Press `ctrl+c` to end the playtest session. Once ended, the latest installed version will remain unless you revert to a previous version using [`devvit install`](#devvit-install). For more information, see the [playtest page](playtest.md).
+You do not need to run `devvit upload` before using `devvit playtest`.
+
#### Usage
```bash
@@ -335,7 +337,7 @@ $ npx devvit update app
### devvit upload
-Upload an app to the App directory. By default the app is private and visible only to you.
+Upload an app to the App directory as a private build. By default the app is private and visible only to you. This command is not required for playtest.
#### Usage
@@ -353,6 +355,42 @@ $ npx devvit upload [--bump major|minor|patch|prerelease] [--copyPaste]
Copy-paste the auth code instead of opening a browser
+### devvit publish
+
+Submit an app version for Reddit review. Use this when you are ready to launch an app beyond your private development flow.
+
+#### Usage
+
+```bash
+$ npx devvit publish [--bump major|minor|patch] [--version ] [--public]
+```
+
+#### Optional arguments
+
+- `--bump