diff --git a/README.md b/README.md
index 40b901173..c66173f5f 100644
--- a/README.md
+++ b/README.md
@@ -44,3 +44,15 @@ $ yarn start
```
This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.
+
+### Share the Devvit AI Helper
+
+Use [https://developers.reddit.com/docs/?ask=1](https://developers.reddit.com/docs/?ask=1) to open the Kapa widget directly. Visitors can also open the helper with the **Ask AI** widget in the bottom-right corner of any docs page.
+
+To prefill a question, add a URL-encoded `question` parameter, for example:
+
+```text
+https://developers.reddit.com/docs/?ask=1&question=How%20do%20I%20get%20started%3F
+```
+
+The question is prefilled for the visitor to review and submit. The `ask=1` parameter also works on individual documentation pages, allowing a shared link to keep that page as context. Kapa's knowledge sources are configured separately in the Kapa platform.
diff --git a/docs/guides/faq.mdx b/docs/guides/faq.mdx
index c0f6c655e..2ba1be159 100644
--- a/docs/guides/faq.mdx
+++ b/docs/guides/faq.mdx
@@ -4,18 +4,30 @@
### Getting Started
+
+
+Should I use Devvit or the Reddit Data API?
+
+Use **Devvit** to build apps that run on Reddit, including games, interactive posts, and moderation tools. Reddit hosts the app, and Devvit manages its Reddit authentication. Start with the [App quickstart](../quickstart/quickstart.md) or [Mod tool quickstart](../quickstart/quickstart-mod-tool.md).
+
+If you're building an **external script, bot, website, or integration** with tools like Python, PRAW, or n8n, follow the [Reddit Data API guidance](https://support.reddithelp.com/hc/en-us/articles/16160319875092-Reddit-Data-API-Wiki). A Devvit login doesn't issue a client ID or client secret for an external application. For a use case that Devvit doesn't support, [request access through Reddit Help](https://support.reddithelp.com/hc/en-us/requests/new?tf_42139884615700=api_request_type_developer_clone&ticket_form_id=14868593862164). Access requires approval under the [Responsible Builder Policy](https://support.reddithelp.com/hc/en-us/articles/42728983564564-Responsible-Builder-Policy).
+
+External Data API access has its own approval process and terms. For commercial data access, use the [commercial access request form](https://support.reddithelp.com/hc/en-us/requests/new?tf_42139884615700=api_request_type_enterprise_clone&ticket_form_id=14868593862164).
+
+
+
Do I need a Reddit API key, client ID, or client secret to build with Devvit?
-No. If you're building a Devvit app, you don't need to create a traditional Reddit app at [`reddit.com/prefs/apps`](https://www.reddit.com/prefs/apps) or manage API keys yourself.
+No. Devvit handles authentication for your app, so you don't need to create an app at [`reddit.com/prefs/apps`](https://www.reddit.com/prefs/apps) or manage API keys yourself.
-Instead, start from the [App quickstart](../quickstart/quickstart.md) or create a project at [developers.reddit.com/new](https://developers.reddit.com/new). During setup, you sign in with your Reddit account and connect it to Reddit developers. Devvit handles authentication for your app.
+Start with the [App quickstart](../quickstart/quickstart.md) or create a project at [developers.reddit.com/new](https://developers.reddit.com/new). During setup, sign in with your Reddit account.
To read or write Reddit content from a Devvit app, enable the Reddit capability described in the [Reddit API Overview](../capabilities/server/reddit-api.mdx).
:::note
-If you're building an external script, bot, or website outside Devvit, that's a different authentication flow from the one documented here.
+For an external script or integration, follow the [Reddit Data API guidance](https://support.reddithelp.com/hc/en-us/articles/16160319875092-Reddit-Data-API-Wiki) to request access. Signing in with Devvit doesn't provide external API credentials.
:::
@@ -24,9 +36,9 @@ If you're building an external script, bot, or website outside Devvit, that's a
Where do I start building a Devvit app?
-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.
+Start with the [App quickstart](../quickstart/quickstart.md) to create a project, connect your Reddit account, and run your first playtest.
-If you already know what you want to build, you can also start with:
+You can also choose a guide for your app or game engine:
- [Quickstart for Games](../quickstart/quickstart.md)
- [Quickstart for Mod Tools](../quickstart/quickstart-mod-tool.md)
@@ -37,7 +49,7 @@ If you already know what you want to build, you can also start with:
-How do I log in, and how do I know I am authenticated?
+How do I log in and check which account I'm using?
Use the CLI to sign in with your Reddit account:
@@ -45,7 +57,7 @@ Use the CLI to sign in with your Reddit account:
npx devvit login
```
-To confirm which account is currently authenticated, run:
+To check which account you're signed in with, run:
```bash
npx devvit whoami
@@ -63,11 +75,9 @@ For command details, see the [`devvit login`](./tools/devvit_cli.mdx#devvit-logi
Can I test locally without uploading to Reddit?
-Not completely. Devvit apps run against Reddit, so the normal development flow uses a playtest subreddit rather than a purely local setup.
-
-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).
+Not completely. Backend calls require Reddit, so use a playtest subreddit to test the full app.
-If you're wondering why a purely local setup isn't enough, the quickstart calls this out directly: backend calls don't work when you test the app only locally.
+Run `npm run dev` from a quickstart project to start a playtest session. See [Playtest](./tools/playtest.md) for more options.
@@ -75,15 +85,15 @@ If you're wondering why a purely local setup isn't enough, the quickstart calls
Why does npm run dev, playtest, upload, or install fail?
-Most development errors fall into a few buckets:
+Check the error message, then try the matching steps:
-- Authentication: make sure you're logged in with `npx devvit login`, then verify the current account with `npx devvit whoami`.
-- Build output mismatch: if Devvit can't find `config.server.entry`, check that your built server file matches the path in `devvit.json`, and that your server build outputs a CommonJS bundle. The best references are [Devvit configuration](../capabilities/devvit-web/devvit_web_configuration.md) and [Vite](./tools/vite.mdx).
-- Config validation: if `devvit.json` complains about invalid fields, extra properties, or settings shapes, validate it against the schema and configuration rules in [Devvit configuration](../capabilities/devvit-web/devvit_web_configuration.md).
-- Fetch or domain errors: if fetch is disabled or a domain is rejected, configure `permissions.http` correctly and review the rules in [HTTP fetch](../capabilities/server/http-fetch.mdx).
-- Runtime failures during playtest or install: use [Playtest](./tools/playtest.md) and [Logs and Debugging](./tools/logs.md) together so you can see the failing endpoint or trigger.
+- **Authentication:** sign in with `npx devvit login`, then check the account with `npx devvit whoami`.
+- **Build output:** if Devvit can't find `config.server.entry`, check that the built server file matches the path in `devvit.json` and that your build outputs a CommonJS bundle. See [Devvit configuration](../capabilities/devvit-web/devvit_web_configuration.md) and [Vite](./tools/vite.mdx).
+- **Configuration:** for invalid fields or extra properties in `devvit.json`, check the schema and rules in [Devvit configuration](../capabilities/devvit-web/devvit_web_configuration.md).
+- **Fetch or domain access:** check `permissions.http` and the requirements in [HTTP fetch](../capabilities/server/http-fetch.mdx).
+- **Runtime errors:** inspect the logs to find the failing endpoint or trigger. See [Playtest](./tools/playtest.md) and [Logs and Debugging](./tools/logs.md).
-One other common gotcha: Devvit projects use `vite build --watch` rather than a normal `vite dev` server. The [Vite guide](./tools/vite.mdx) explains the expected setup.
+For Vite projects, use `vite build --watch` for playtesting. See the [Vite guide](./tools/vite.mdx) for the setup.
@@ -91,19 +101,22 @@ One other common gotcha: Devvit projects use `vite build --watch` rather than a
How do I update the Devvit CLI?
-Prefer updating the project-local CLI dependency instead of relying on a global install. Update `devvit` in your project, then run `npx devvit update app` so your `@devvit` packages match the CLI.
+Update the `devvit` dependency in your project, then run `npx devvit update app` to update your `@devvit` packages to match the CLI.
-For the current commands and workflow, see [Devvit CLI](./tools/devvit_cli.mdx) and the update notes in [Changelog](../changelog.md).
+See [Devvit CLI](./tools/devvit_cli.mdx) for commands and the [Changelog](../changelog.md) for release notes.
+
How do I update my app version?
-Updating the CLI and publishing a new app version are separate steps. Your app version changes when you publish: `npx devvit publish` creates the next launch version, and you can control that with `--bump` or `--version` as described in [Launch your app](./launch/launch-guide.md).
+Run `npx devvit publish` to submit a new app version for review. Use `--bump` or `--version` to control the version number. See [Launch your app](./launch/launch-guide.md) for the publishing steps.
-After that, the subreddit still needs to be on the version you want installed. Publishing a new version doesn't automatically update every subreddit. Use [`devvit install`](./tools/devvit_cli.mdx#devvit-install) or open your app in the [App Directory](https://developers.reddit.com/apps/) and, under **Installed in communities**, use the blue **Update** button for the subreddit that's out of date.
+Publishing doesn't automatically update every subreddit. Once the version is approved, use [`devvit install`](./tools/devvit_cli.mdx#devvit-install) to update a community you moderate. You can also open your app in the [App Directory](https://developers.reddit.com/apps/), find the subreddit under **Installed in communities**, and select **Update**.
+
+Your app version is separate from the Devvit CLI and SDK versions. Updating your development tools doesn't publish or install a new version of your app.
@@ -111,11 +124,11 @@ After that, the subreddit still needs to be on the version you want installed. P
I published and it says a new Devvit version is available. Do I need to upgrade?
-Not necessarily. If you're within 2–3 versions of the current Devvit release, your app will continue working as-is. The version notice is informational — it doesn't mean your app is broken or blocked from publishing.
+Check the [Changelog](../changelog.md) for breaking changes, migration steps, and upgrade requirements for your project's version. The notice means a newer Devvit release is available.
-Staying reasonably current is good practice, though. It gets you access to the latest fixes and capabilities. When you're ready, run `npx devvit update app` to bring your project's `@devvit` packages in line with the latest CLI, then test in playtest before publishing the update.
+To upgrade, update the `devvit` dependency in your project, then run `npx devvit update app` to update your `@devvit` packages to match. Test in playtest before publishing.
-For upgrade steps, see [Devvit CLI](./tools/devvit_cli.mdx) and the [Changelog](../changelog.md).
+See [Devvit CLI](./tools/devvit_cli.mdx) for upgrade commands.
@@ -123,7 +136,7 @@ For upgrade steps, see [Devvit CLI](./tools/devvit_cli.mdx) and the [Changelog](
What is the difference between npx devvit upload and npx devvit publish?
-Use `npx devvit upload` when you want a private uploaded build for yourself, and use `npx devvit publish` when you're ready to submit a version for launch review. In practice, playtest is still the normal dev loop, `upload` is useful for a private installable build, and `publish` is the launch step documented in [Launch your app](./launch/launch-guide.md).
+Use `npx devvit upload` to create a private build you can install. Use `npx devvit publish` to submit a version for launch review. For day-to-day development, use [Playtest](./tools/playtest.md).
For command syntax, see [Devvit CLI](./tools/devvit_cli.mdx). For the review and launch flow, see [Launch your app](./launch/launch-guide.md).
@@ -133,37 +146,47 @@ For command syntax, see [Devvit CLI](./tools/devvit_cli.mdx). For the review and
Why does npx devvit upload say assets uploaded, then fail with "You must be logged in to upload a new app version"?
-This usually means your local Devvit authentication state is stale or corrupted. The asset upload can finish before the CLI fails while creating the new app version.
-
-Reset your local Devvit auth state, then log in again.
+Assets upload separately from the app version, so that step can succeed even when app version creation fails.
-On Windows PowerShell:
+First, refresh your CLI session and check that you're using the expected Reddit account:
-```powershell
+```bash
npx devvit logout
-Remove-Item -Recurse -Force "$env:USERPROFILE\.devvit"
npx devvit login
+npx devvit whoami
```
-On macOS, Linux, or WSL:
+Then retry the upload or playtest. If it still fails, capture the error with `--verbose` and share it with your CLI version and operating system in the [Devvit Discord](https://developers.reddit.com/discord) or [r/Devvit](https://www.reddit.com/r/Devvit). Keep the token stored in `~/.devvit/token` private.
+
+See [Devvit CLI](./tools/devvit_cli.mdx) for authentication and upload options.
+
+
+
+
+
+How do I view live and historical app logs, including timestamps?
+
+Use `npx devvit logs` for an installed app. For example, to show the last two hours of logs with timestamps and continue streaming new logs:
```bash
-npx devvit logout
-rm -rf ~/.devvit
-npx devvit login
+npx devvit logs r/mySubreddit my-app --since 2h --verbose
```
-After logging in, run `npx devvit whoami` to confirm the CLI is using the expected Reddit account, then try `npx devvit upload` again.
+Omit `--since 2h` to start with new logs, or change the interval to values such as `30m` or `1d`. From the app's project directory, you can omit `my-app`. These commands also work in PowerShell.
+
+Logs are limited to 5,000 events or up to seven days. Playtest already streams logs from its test community. Use `console.log()`, `console.info()`, or `console.error()` in server code to create logs; inspect browser developer tools for client-side messages.
+
+See [Logs and Debugging](./tools/logs.md) and the [CLI logs reference](./tools/devvit_cli.mdx#devvit-logs).
-What should I do after playtest when I am ready to launch?
+How do I launch my app after playtesting?
-Before launch, make sure the app is stable across mobile and web, test with multiple accounts, and add the required app [`README.md`](../devvit_rules.md#app-readme-requirements). Then follow the publish flow in [Launch your app](./launch/launch-guide.md).
+Test your app on mobile and web with multiple accounts, and add the required app [`README.md`](../devvit_rules.md#app-readme-requirements). Then follow [Launch your app](./launch/launch-guide.md) to publish.
-If you're just ending a playtest session, remember that the latest playtest install remains in place until you change installs. [Playtest](./tools/playtest.md) and [`devvit install`](./tools/devvit_cli.mdx#devvit-install) cover that handoff.
+Ending a playtest leaves the last playtest build installed in the test subreddit. See [Playtest](./tools/playtest.md) and [`devvit install`](./tools/devvit_cli.mdx#devvit-install) to manage that installation.
@@ -171,11 +194,11 @@ If you're just ending a playtest session, remember that the latest playtest inst
How long does it take to get my app published?
-Most app versions are reviewed within **1–2 business days**. New apps or versions that include higher-risk features may take longer. Features that commonly extend review time:
+Most app versions are reviewed within **1–2 business days**. New apps and versions that need additional review may take longer, including those with:
- **Payments**: apps using the payments capability go through additional policy review.
- **`runAs: 'USER'`**: user action permissions require explicit approval as part of the review.
-- **External fetch domains**: new domain requests are reviewed separately under the same **1–2 business day** target, though requests with policy ambiguity may take longer (see [HTTP Fetch](../capabilities/http-fetch.mdx)).
+- **External fetch domains**: domain requests are reviewed separately, usually within **1–2 business days**. Requests that need policy clarification may take longer. See [HTTP Fetch](../capabilities/http-fetch.mdx).
To keep review moving:
@@ -183,7 +206,7 @@ To keep review moving:
- Ensure your app complies with the [Devvit Rules](../devvit_rules.md).
- If your app uses fetch domains, document them in a "Fetch Domains" section of your [README](../devvit_rules.md#app-readme-requirements).
-If you haven't heard back after a week, reach out in the [Devvit Discord](https://developers.reddit.com/discord) or via [r/Devvit Modmail](https://www.reddit.com/message/compose/?to=r/Devvit). For the full publish flow, see [Launch your app](./launch/launch-guide.md).
+If you haven't heard back after a week, ask in the [Devvit Discord](https://developers.reddit.com/discord) or contact [r/Devvit Modmail](https://www.reddit.com/message/compose/?to=r/Devvit). See [Launch your app](./launch/launch-guide.md) for the full process.
@@ -191,9 +214,9 @@ If you haven't heard back after a week, reach out in the [Devvit Discord](https:
How do I install my app on another subreddit?
-If you moderate the destination subreddit, use [`devvit install`](./tools/devvit_cli.mdx#devvit-install) to install a specific app or version on that community. That's the direct CLI path when you want to move beyond the playtest subreddit or test on another subreddit you control.
+Use [`devvit install`](./tools/devvit_cli.mdx#devvit-install) to install your app in a subreddit you moderate.
-If the goal is broader distribution, follow [Launch your app](./launch/launch-guide.md) so moderators can install the approved app in the appropriate way for its visibility level.
+To make your app available to other moderators, follow [Launch your app](./launch/launch-guide.md) and choose the visibility level that fits your app.
@@ -201,9 +224,11 @@ If the goal is broader distribution, follow [Launch your app](./launch/launch-gu
What is the difference between unlisted and public apps?
-Published apps are unlisted by default. That's usually the right fit for games and single-community tools. If you want your app to appear in the App Directory so any moderator can install it, use `npx devvit publish --public` and follow the listing guidance in [Launch your app](./launch/launch-guide.md).
+Published apps are unlisted by default. Unlisted apps don't appear in the App Directory and work well for games and tools built for a specific community.
+
+To list your app in the App Directory so other moderators can find and install it, use `npx devvit publish --public`. See [Launch your app](./launch/launch-guide.md) for listing requirements.
-All apps submitted for review should look launch-ready: the launch docs require an app [`README.md`](../devvit_rules.md#app-readme-requirements), and game launch guidance expects a custom launch or first screen rather than a rough default experience.
+Before submitting either type for review, add the required app [`README.md`](../devvit_rules.md#app-readme-requirements). Games also need a custom first screen.
@@ -213,7 +238,7 @@ All apps submitted for review should look launch-ready: the launch docs require
What is an interactive post in Devvit?
-An interactive post is a Reddit post created for an app experience rather than a plain text-only post. That means creating the post with `reddit.submitCustomPost()` and defining how it launches through entry points, launch screens, and optional `postData`. See [Interactive posts overview](../capabilities/interactive-posts/interactive_posts_overview.mdx) and [Creating a custom post](../capabilities/creating_custom_post.md).
+An interactive post runs an app experience inside a Reddit post. Create one with `reddit.submitCustomPost()` and configure its views through entry points and launch screens. You can attach data with `postData`. See [Interactive posts overview](../capabilities/interactive-posts/interactive_posts_overview.mdx) and [Creating a custom post](../capabilities/creating_custom_post.md).
@@ -221,7 +246,7 @@ An interactive post is a Reddit post created for an app experience rather than a
Why is my post just text instead of an interactive app post?
-If you call `submitPost()` with normal `text`, you're creating a regular Reddit post. To create an interactive app post, use `submitCustomPost()` and point it at your configured entry point instead. The [Interactive posts overview](../capabilities/interactive-posts/interactive_posts_overview.mdx) is the clearest starting point for that distinction.
+`submitPost()` with `text` creates a regular text post. To create an interactive app post, use `submitCustomPost()` with your configured entry point. See [Interactive posts overview](../capabilities/interactive-posts/interactive_posts_overview.mdx).
@@ -229,22 +254,24 @@ If you call `submitPost()` with normal `text`, you're creating a regular Reddit
What is Devvit Web?
-Devvit Web is the current client/server app model for building Devvit apps with standard web tools like React, Phaser, or Three.js. It's a normal web app plus server endpoints plus `devvit.json` configuration, with Reddit capabilities split between client APIs, server APIs, and config. See [Devvit Web overview](../capabilities/devvit-web/devvit_web_overview.mdx).
+Devvit Web lets you build apps for Reddit with web tools such as React, Phaser, and Three.js. Your app includes a web client, server endpoints, and a `devvit.json` configuration file. Client and server APIs give your app access to Reddit features. See [Devvit Web overview](../capabilities/devvit-web/devvit_web_overview.mdx).
+
-I got a notice that Blocks is deprecated. What do I need to do?
+How do I migrate a Blocks app to Devvit Web?
-Blocks is being replaced by [Devvit Web](../capabilities/devvit-web/devvit_web_overview.mdx). The path depends on how your app is built, but here's what to check first:
+Migrate your app to [Devvit Web](../capabilities/devvit-web/devvit_web_overview.mdx). Start with the parts your app uses:
- **`devvit.yaml`**: If your project still has a `devvit.yaml`, replace it with a `devvit.json`. See [Migrating Blocks/Mod Tools to Devvit Web](./migrate/devvit-singleton.md) for the updated config format and steps.
-- **`Devvit.addCustomPostType()`**: This is the core Blocks API and is deprecated. Move your post rendering to a `client` entry in `devvit.json`, backed by a standard HTML, React, or other web app.
-- **`submitCustomPost()` with `preview`**: The `preview` field (used to render a Blocks component as the post preview) is no longer the right pattern. Use `post.entrypoints` in `devvit.json` to define your inline and expanded views as HTML entry points instead.
+- **`Devvit.addCustomPostType()`**: Replace this deprecated Blocks API with a `client` entry in `devvit.json`, backed by an HTML, React, or other web app.
+- **`submitCustomPost()` with `preview`**: Replace the Blocks preview with HTML entry points. Use `post.entrypoints` in `devvit.json` to define your inline and expanded views.
- **`useWebView`**: If your app launched a web view from inside Blocks, migrate to Devvit Web. See [Migrating from useWebView to Devvit Web](./migrate/inline-web-view.md).
+- **`splash`**: Replace the legacy `submitCustomPost()` splash parameter with HTML entry points and select one using `entry`. See [Migrating from Splash Screens](../capabilities/server/launch_screen_and_entry_points/splash_migration.mdx).
-If your app uses only Blocks without a web view, [Migrating Blocks/Mod Tools to Devvit Web](./migrate/devvit-singleton.md) is the quickest path. If your app has a web view, start with [Migrating from useWebView to Devvit Web](./migrate/inline-web-view.md).
+For a Blocks app without a web view, follow [Migrating Blocks/Mod Tools to Devvit Web](./migrate/devvit-singleton.md). For an app with a web view, follow [Migrating from useWebView to Devvit Web](./migrate/inline-web-view.md).
@@ -252,27 +279,48 @@ If your app uses only Blocks without a web view, [Migrating Blocks/Mod Tools to
Where do I customize the first screen or launch screen?
-For current Devvit Web apps, customize the first screen through your `post.entrypoints` in `devvit.json` and the HTML, CSS, and client code for those entry files. 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).
+Configure `post.entrypoints` in `devvit.json`, then edit the HTML, CSS, and client code for the entry point shown when the post opens.
+
+See [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).
-
-
-Should I use the legacy splash field or HTML launch entry points?
+
+
+
+How do I configure inline and expanded views?
+
+Define the views under `post.entrypoints` in `devvit.json`. For example:
+
+```json title="devvit.json"
+{
+ "post": {
+ "dir": "dist/client",
+ "entrypoints": {
+ "default": { "entry": "src/client/preview.html", "height": "regular" },
+ "game": { "entry": "src/client/game.html" }
+ }
+ }
+}
+```
-:::warning
-**Deprecation notice**: The `splash` parameter in `submitCustomPost()` and Blocks-based launch screens will be deprecated in June. Migrate to HTML-based entry points before then.
-:::
+With the [Devvit Vite plugin](./tools/vite.mdx), these `entry` paths point to source HTML files. Create the post with `entry: 'default'` to show that view inline. The `inline` config field is deprecated; entry points load inline without it.
-Use HTML launch entry points for all new and existing work. The older `splash` parameter is deprecated in favor of entrypoint-based launch screens and `entry` selection in `submitCustomPost()`. If you're updating an older app, start with [Migrating from Splash Screens](../capabilities/server/launch_screen_and_entry_points/splash_migration.mdx).
+To open the game in expanded mode, call `requestExpandedMode()` synchronously from a user click in your client:
-
+```ts
+import { requestExpandedMode } from '@devvit/web/client';
-
-
-How do I handle scrolling and touch gestures in inline vs expanded mode?
+document.querySelector('#play')?.addEventListener('click', (event) => {
+ requestExpandedMode(event, 'game');
+});
+```
+
+In Devvit 0.15, you can also call `requestExpandedMode()` while already expanded to open a different entry point. Expansion must follow a user action; apps can't automatically force fullscreen.
-Treat inline and expanded mode differently. Inline should avoid scroll traps and heavy gesture hijacking so users can still scroll past the post, while expanded is the right place for richer touch interaction and more space.
+Inline mode accepts taps and clicks, and must let users scroll past the post without scroll traps, zoom, or pan interference. Use expanded mode for richer gestures. Store state that both views need on the server, such as in Redis or `postData`, rather than assuming the views share in-memory state.
+
+See [View modes and entry points](../capabilities/server/launch_screen_and_entry_points/view_modes_entry_points.md).
@@ -280,7 +328,7 @@ Treat inline and expanded mode differently. Inline should avoid scroll traps and
How do I add images that ship with my app?
-Put static images in your client `dist/` directory when they should ship with the app version, such as logos, backgrounds, or other bundled art. Reference them directly from your web client (for example via `
`).
+Include static images, such as logos and backgrounds, in your client build output (`dist/`). Reference them from your web client, for example with `
`.
@@ -288,7 +336,7 @@ Put static images in your client `dist/` directory when they should ship with th
How do user image uploads work in Devvit?
-The simplest path is a form field with `type: 'image'`, which returns a Reddit-hosted image URL when the user submits it. For custom flows like screenshots or generated images, send the data to your server and upload it with [Media uploads](../capabilities/server/media-uploads.mdx).
+Use a form field with `type: 'image'` to get a Reddit-hosted image URL when the user submits the form. For screenshots or generated images, send the data to your server and upload it with [Media uploads](../capabilities/server/media-uploads.mdx).
See [Forms](../capabilities/client/forms.mdx) and [Media uploads](../capabilities/server/media-uploads.mdx) for the supported formats and size limits.
@@ -308,23 +356,18 @@ Try compressing the image, reducing dimensions, or retrying from a faster connec
What image URLs can I use in a Devvit app?
-The documented display paths are bundled client assets, Reddit-hosted URLs, and SVG data URLs, depending on the UI surface. If your source image lives somewhere else on the web, don't assume you can hotlink it directly into the UI. Upload it first so Reddit hosts the image, then use the returned URL. See [Media uploads](../capabilities/server/media-uploads.mdx).
+Use bundled client assets, Reddit-hosted URLs, or SVG data URLs, depending on the UI surface. For an image hosted elsewhere, upload it to Reddit first and use the returned URL. See [Media uploads](../capabilities/server/media-uploads.mdx).
-
-What is postData, and when should I use it instead of Redis?
-
-Use `postData` for small shared JSON attached to a single post, like lightweight game state or configuration that all viewers need to read. The docs cap it at 2 KB per post and recommend [Redis](../capabilities/server/redis.mdx) for larger or more persistent data patterns.
-
-
-
-How do I access or update postData?
+How do I use postData, and when should I use Redis?
+
+Use `postData` for small JSON objects shared by everyone viewing a post, such as game configuration. It's limited to 2 KB per post. Use [Redis](../capabilities/server/redis.mdx) for larger datasets or data shared across posts.
-Set `postData` when creating the post, then read it from `context.postData` on either the client or server side. To update it later, fetch the post and call `setPostData()`. The important gotcha is that `setPostData()` replaces the whole object, so merge existing fields first. See [Post data](../capabilities/server/post-data.mdx).
+Set `postData` when creating the post, then read it from `context.postData` on the client or server. To update it, fetch the post and call `setPostData()`. This replaces the whole object, so merge any fields you want to keep before saving. See [Post data](../capabilities/server/post-data.mdx).
@@ -332,9 +375,7 @@ Set `postData` when creating the post, then read it from `context.postData` on e
How do I build a leaderboard with Redis?
-The standard Devvit pattern is to build leaderboards with Redis sorted sets. Use [Redis](../capabilities/server/redis.mdx) for score storage and ranking, use [Scheduler](../capabilities/server/scheduler.mdx) for daily or periodic resets, and prefer realtime updates over constant polling when you need a live leaderboard.
-
-Redis is the right storage layer, but the exact schema depends on whether you need daily, weekly, or all-time rankings. [Redis](../capabilities/server/redis.mdx) is the best starting point.
+Use [Redis sorted sets](../capabilities/server/redis.mdx) to store scores and rank players, and [Scheduler](../capabilities/server/scheduler.mdx) for daily or periodic resets. For a live leaderboard, use realtime updates to send score changes to connected clients.
@@ -342,7 +383,7 @@ Redis is the right storage layer, but the exact schema depends on whether you ne
Can a menu action create a new post?
-Yes. Define the menu item in `devvit.json`, implement the server endpoint it calls, and create the post from that route. The pattern is documented across [Menu actions](../capabilities/client/menu-actions.mdx) and [Interactive posts overview](../capabilities/interactive-posts/interactive_posts_overview.mdx).
+Yes. Define the menu item in `devvit.json`, implement its server endpoint, and create the post from that endpoint. See [Menu actions](../capabilities/client/menu-actions.mdx) and [Interactive posts overview](../capabilities/interactive-posts/interactive_posts_overview.mdx).
@@ -350,7 +391,7 @@ Yes. Define the menu item in `devvit.json`, implement the server endpoint it cal
How do I automate daily or scheduled game posts?
-Use [Scheduler](../capabilities/server/scheduler.mdx) for cron-style recurring jobs or one-off jobs declared in `devvit.json`, then handle the matching `/internal/...` endpoint in your server code. The scheduler docs explain the plumbing; the post creation step still uses the normal Reddit APIs like `submitCustomPost()`.
+Define a recurring or one-time job with [Scheduler](../capabilities/server/scheduler.mdx) in `devvit.json`. In the matching `/internal/...` server endpoint, call `reddit.submitCustomPost()` to create the post.
@@ -358,7 +399,7 @@ Use [Scheduler](../capabilities/server/scheduler.mdx) for cron-style recurring j
How do I post or comment as the user instead of the app?
-Add the required `permissions.reddit.asUser` entries in `devvit.json`, then call the supported Reddit APIs with `runAs: 'USER'`. The main doc for this is [User Actions](../capabilities/server/userActions.mdx), which also explains the review requirements, explicit opt-in rules, and `userGeneratedContent` expectations.
+Add the required `permissions.reddit.asUser` entries in `devvit.json`, then call the supported Reddit APIs with `runAs: 'USER'`. Follow [User Actions](../capabilities/server/userActions.mdx) for review requirements, user opt-in, and `userGeneratedContent` requirements.
@@ -366,7 +407,7 @@ Add the required `permissions.reddit.asUser` entries in `devvit.json`, then call
Why does runAs: 'USER' still post as the app during playtest?
-Before the app version is approved, user actions aren't enabled for everyone. During playtest or other unapproved versions, `runAs: 'USER'` falls back to the app account for most users, while actions taken by the app owner are attributed to the owner's username. After publishing and approval, it operates on behalf of the user for all users. See [User Actions](../capabilities/server/userActions.mdx).
+During playtest or with an unapproved app version, `runAs: 'USER'` uses the app account for most users. Actions taken by the app owner use the owner's username. Once the app version is published and approved, user actions run on behalf of each user. See [User Actions](../capabilities/server/userActions.mdx).
@@ -376,25 +417,55 @@ Before the app version is approved, user actions aren't enabled for everyone. Du
Devvit supports both user flair and post flair through the Reddit API client.
-- For a new post, use the submit options documented in [CommonSubmitPostOptions](../api/redditapi/models/type-aliases/CommonSubmitPostOptions.md), including `flairId` or `flairText`.
+- For a new post, use `flairId` or `flairText` in [CommonSubmitPostOptions](../api/redditapi/models/type-aliases/CommonSubmitPostOptions.md).
- For an existing post, use the flair methods on [RedditClient](../api/redditapi/RedditClient/classes/RedditClient.md), such as `setPostFlair()` and `removePostFlair()`.
- For a user, use `setUserFlair()`, `removeUserFlair()`, or `setUserFlairBatch()` on the same client.
-If you're reading flair back from a post, note that post flair and author flair are different fields. The [Post](../api/redditapi/models/classes/Post.md) model exposes `flair` for the post and `authorFlair` for the post author.
+To apply an existing subreddit flair template when creating an interactive post:
+
+```ts
+import { reddit } from '@devvit/web/server';
+
+const post = await reddit.submitCustomPost({
+ subredditName: 'mySubreddit',
+ title: 'Daily game',
+ entry: 'default',
+ flairId: 'your-flair-template-id',
+});
+```
+
+To preserve existing flair, fetch the subreddit and call `subreddit.getUserFlair({ usernames: ['username'] })` first. Its `users` array includes `flairText` and `flairCssClass`. Combine the values you want to keep with your changes before calling `setUserFlair()`, which replaces the flair. See [getUserFlair](../api/redditapi/models/classes/Subreddit.md#getuserflair).
+
+On the [Post](../api/redditapi/models/classes/Post.md) model, `flair` contains the post's flair and `authorFlair` contains the author's flair.
-If you need to react to flair changes, Devvit documents an [`onPostFlairUpdate`](../capabilities/server/triggers.mdx) trigger for post flair changes. Also note that the [Devvit test tool](./tools/devvit_test.mdx) doesn't yet support the Flair service.
+Use the [`onPostFlairUpdate`](../capabilities/server/triggers.mdx) trigger to react to post flair changes. The [Devvit test tool](./tools/devvit_test.mdx) doesn't yet support the Flair service.
+
-How do I get a user's username or snoovatar?
+How do I get usernames, user avatars, and subreddit icons?
+
+Use `getCurrentUsername()` when you only need the current user's name.
+
+For more profile information, use `getCurrentUser()` from the [Reddit API client](../api/redditapi/RedditClient/classes/RedditClient.md). To get a snoovatar URL, use `reddit.getSnoovatarUrl(username)` or `user.getSnoovatarUrl()` on the [User](../api/redditapi/models/classes/User.md) model.
-If you only need the current user's name, prefer `getCurrentUsername()` over fetching the full user object.
+Some handlers also expose experimental `username` and `snoovatar` fields on [BaseContext](../api/public-api/type-aliases/BaseContext.md).
-If you need more profile information, use `getCurrentUser()` from the [Reddit API client](../api/redditapi/RedditClient/classes/RedditClient.md). To get a snoovatar URL, use `reddit.getSnoovatarUrl(username)` or `user.getSnoovatarUrl()` on the [User](../api/redditapi/models/classes/User.md) model.
+For a subreddit icon, fetch its styles by subreddit ID in your server code:
-Some handlers also expose experimental identity fields like `username` and `snoovatar` on [BaseContext](../api/public-api/type-aliases/BaseContext.md), but the Reddit client methods are the clearest documented path.
+```ts
+import { reddit } from '@devvit/web/server';
+
+const subreddit = await reddit.getCurrentSubreddit();
+const styles = await reddit.getSubredditStyles(subreddit.id);
+const iconUrl = styles.icon;
+```
+
+To look up another community, get its ID with `reddit.getSubredditInfoByName(name)` first. See [getSubredditStyles](../api/redditapi/RedditClient/classes/RedditClient.md#getsubredditstyles) and [SubredditStyles](../api/redditapi/models/type-aliases/SubredditStyles.md#icon).
+
+Icon and snoovatar URLs can be absent, so provide a fallback image or initials.
@@ -402,27 +473,33 @@ Some handlers also expose experimental identity fields like `username` and `snoo
How do I handle external links in Devvit?
-Use Devvit navigation APIs to open links rather than treating this like external fetch. For app navigation, see [Navigation](../capabilities/client/navigation.mdx), which covers `navigateTo` and the confirmation flow for external URLs.
+Use `navigateTo` to open a link. External URLs require user confirmation. See [Navigation](../capabilities/client/navigation.mdx).
-If you actually need remote data or remote media, that's a different path: use [HTTP fetch](../capabilities/server/http-fetch.mdx) for approved server-side fetches, and [Media uploads](../capabilities/server/media-uploads.mdx) when you need a Reddit-hosted media URL.
+To retrieve external data, use [HTTP fetch](../capabilities/server/http-fetch.mdx) from your server. To host an image or video on Reddit, use [Media uploads](../capabilities/server/media-uploads.mdx).
+
+
-How do I update my app profile settings?
+How do I update my app's icon and profile settings?
+
+Set your app's profile icon with `marketingAssets.icon` in `devvit.json`. Use a **1024 × 1024 PNG** and a path relative to the project root:
-App profile settings let you control how your app appears on Reddit via a combination of configuration in `devvit.json` and fields in the Developer Portal.
+```json title="devvit.json"
+{
+ "marketingAssets": {
+ "icon": "assets/icon.png"
+ }
+}
+```
-**Avatar (profile icon)**
-To update your avatar:
+Publish your app and submit it for review. Once approved, the icon appears on your app's Reddit profile. To change it, update the image and submit a new app version for review. Apps support image avatars only; Snoovatars aren't supported.
-1. In your `devvit.json`, set the `marketingAssets.icon` field to the path to your icon from the project root.
-2. When you publish your app and it is approved, this icon is uploaded to your app’s Reddit profile.
-3. To change the icon later, update `marketingAssets.icon` in `devvit.json` and submit the app for a new review.
-4. Only image avatars are supported at this time. Snoovatars are not supported for apps.
+If the profile still shows the old image, check that the version containing the new icon has been approved. See [Marketing assets configuration](../capabilities/devvit-web/devvit_web_configuration.md#marketing-assets).
-You can also edit the display name, about description, and mature flag (18+) fields in the Developer Portal under Developer Settings. Updates will appear in the Developer Portal and on the app's Reddit profile.
+For the display name, about description, and mature flag (18+), open **Developer Settings** in the Developer Portal. These changes appear in the portal and on the app's Reddit profile.
@@ -432,16 +509,18 @@ You can also edit the display name, about description, and mature flag (18+) fie
What are the main storage, payload, and rate limits?
-There's no single limits page today, but these are the most commonly referenced numbers in the docs:
+The main limits are:
-- [Redis](../capabilities/server/redis.mdx): 5 GB max storage per installation, 5 MB max request size, and 40,000 max commands per second.
-- [Devvit Web](../capabilities/devvit-web/devvit_web_overview.mdx): 30 second max request time, 4 MB max payload size, and 10 MB max response size.
+- [Redis](../capabilities/server/redis.mdx): 5 GB of storage per installation, 5 MB per request, and 40,000 commands per second.
+- [Devvit Web](../capabilities/devvit-web/devvit_web_overview.mdx): 30 seconds per request, a 4 MB request payload, and a 10 MB response.
- [Post data](../capabilities/server/post-data.mdx): 2 KB per post.
- [Settings and secrets](../capabilities/server/settings-and-secrets.mdx): 2 KB per setting value.
- [Realtime](../capabilities/realtime/overview.md): 1 MB maximum message payload and 100 messages per second per installation.
- [Scheduler](../capabilities/server/scheduler.mdx): up to 10 live recurring actions per installation, plus `runJob()` limits documented on that page.
-If you need data to survive app updates, don't rely on browser `localStorage`. The [Devvit Web overview](../capabilities/devvit-web/devvit_web_overview.mdx) recommends Redis for persistent storage across versions.
+**Redis limits apply to each installation of your app in a subreddit.** Posts and users in that installation share its storage allowance. Each subreddit installation has a separate Redis namespace and can't read another installation's keys. See [Redis data storage](../capabilities/server/redis.mdx#data-storage).
+
+Use Redis for data that needs to survive app updates. See the [Devvit Web overview](../capabilities/devvit-web/devvit_web_overview.mdx) for persistence guidance.
@@ -449,39 +528,64 @@ If you need data to survive app updates, don't rely on browser `localStorage`. T
How long does it take to get my domain approved?
-Domain requests are reviewed separately from app publishing. Most domain requests are reviewed within **1–2 business days**, though requests with policy ambiguity may take longer. If your app was approved but a requested fetch domain wasn't yet granted, the domain review may still be in progress.
+Most domain requests are reviewed within **1–2 business days**. Requests that need policy clarification may take longer. Domain review is separate from app review, so your app can be approved while a domain request is still in progress.
-To make approval go smoothly:
+When requesting a domain:
-- Use exact hostnames only — no wildcards (`*.example.com`), no protocols (`https://`), and no paths (`api.example.com/webhooks`).
+- Use exact hostnames, such as `api.example.com`. Omit wildcards, protocols, and paths.
- Add a "Fetch Domains" section to your app [`README.md`](../devvit_rules.md#app-readme-requirements) listing each domain and explaining why you need it. The expected format is documented in [HTTP Fetch](../capabilities/http-fetch.mdx).
- Include links to your Terms and Conditions and Privacy Policy in your app details form.
-Before submitting, check the [global fetch allowlist](../capabilities/http-fetch.mdx#global-fetch-allowlist) — if your domain is already listed there, no separate request is needed. Personal domains (e.g., `personaldomain.com`) aren't approved.
+Check the [global fetch allowlist](../capabilities/http-fetch.mdx#global-fetch-allowlist) first. Domains on that list don't need a separate request. Personal domains, such as `personaldomain.com`, aren't approved.
+
-What screen sizes should I design for?
+How do I set my post height, and what dimensions should I design for?
+
+Set the inline height per entry point in `devvit.json`, for example `"height": "regular"`. The [configuration schema](https://developers.reddit.com/schema/config-file.v1.json) accepts the named heights `short`, `regular`, and `tall`. Config values use lowercase; the custom-post `styles.height` API uses enum values such as `REGULAR` and `TALL`.
-There's no single published pixel size for every device or view mode. Build responsive layouts and test them across the views supported by the [UI Simulator](./tools/ui_simulator.mdx): mobile, desktop, and fullscreen.
+The [custom post style presets](../capabilities/creating_custom_post.md#custom-post-styles) are:
-Inline and expanded mode behave differently: expanded is the larger experience, with more room for rich interaction, while inline should stay lightweight and feed-friendly.
+| Preset | Height |
+| --- | --- |
+| `REGULAR` | 320 px |
+| `TALL` | 512 px |
-Start with mobile-first assumptions and validate in the simulator before hard-coding dimensions. The best references are [View modes and entry points](../capabilities/server/launch_screen_and_entry_points/view_modes_entry_points.md), [Launch screen customization](../capabilities/server/launch_screen_and_entry_points/launch_screen_customization.md), and [UI Simulator](./tools/ui_simulator.mdx).
+Width varies with the viewport, approximately 288–880 px. Expanded mode uses a larger modal on web or fullscreen on mobile, so build responsive layouts and test mobile, desktop, and fullscreen in the [UI Simulator](./tools/ui_simulator.mdx).
+
+For an exact pixel height, use the **experimental** `post.entrypoints..styles.height` setting. It accepts an integer from 72 to 512. For example:
+
+```json title="devvit.json"
+{
+ "post": {
+ "dir": "dist/client",
+ "entrypoints": {
+ "default": {
+ "entry": "src/client/preview.html",
+ "styles": { "height": 180 }
+ }
+ }
+ }
+}
+```
+
+Use an SDK version that supports this experimental setting and validate your config against its schema. This setting is ignored in fullscreen. See [View modes and entry points](../capabilities/server/launch_screen_and_entry_points/view_modes_entry_points.md) for the view configuration.
+
-Can I build NSFW games or apps with Devvit?
+Can my app use NSFW content, and why are NSFW listings empty or showNsfw false?
-There's no separate NSFW platform guide in these docs, so the main source of truth is [Devvit Rules](../devvit_rules.md) plus Reddit's linked platform policies.
+For mature content, follow the [Devvit Rules](../devvit_rules.md), including labeling and age-gating requirements. Uploaded media also goes through the safety checks described in [Media uploads](../capabilities/server/media-uploads.mdx).
-The rules explicitly require labels or age-gating before exposing users to graphic, sexually explicit, or otherwise mature content. Static assets and uploaded media are also subject to the same safety checks and policy review described in [Media uploads](../capabilities/server/media-uploads.mdx).
+The [User model](../api/redditapi/models/classes/User.md#shownsfw) has two separate fields: `showNsfw` indicates whether the user is over 18 and wants to see NSFW content, while `nsfw` indicates whether the profile is marked NSFW. `showNsfw` is read-only. Don't rely on a mature profile label or your personal account's viewing preferences to grant the app access to NSFW content.
-If your app idea depends on adult content or NSFW communities, review those rules first and get clarification in the [Devvit Discord](https://developers.reddit.com/discord) before you ship.
+If a listing unexpectedly returns no posts, try the same API call in a public SFW community. Then contact [r/Devvit Modmail](https://www.reddit.com/message/compose/?to=r/Devvit) with your app name and version, SDK version, target community, API method, and a small example that reproduces the issue. The team can check the access available to your app.
@@ -500,14 +604,35 @@ For help from the Devvit team and community:
+
-How do I uninstall or remove a Devvit app from a subreddit?
+How do I uninstall, delete, or archive an app, or unregister an app account?
+
+**Remove an installation from a subreddit:** use `npx devvit list installs` to inspect your installations, then uninstall from a community you moderate:
+
+```bash
+npx devvit uninstall r/mySubreddit my-app
+```
+
+You can also open the app in the [App Directory](https://developers.reddit.com/apps/), select the subreddit under **Installed in communities**, and choose **Remove from community**. See the [CLI reference](./tools/devvit_cli.mdx#devvit-uninstall).
-Use the CLI to inspect installs and uninstall from a subreddit. The current docs point to `list installs` and `uninstall` in [Devvit CLI](./tools/devvit_cli.mdx).
+Uninstalling can remove the installation's stored data and settings. See [Mod resources](./best-practices/mod_resources.md) before removing an installation.
-There's also a manual path in the [App Directory](https://developers.reddit.com/apps/). Open your app there, then either use **Installed in communities** to select a subreddit and choose **Remove from community**, or scroll to the bottom of the app page and use **Archive** if you want to archive the app itself.
+**Archive the app:** open its App Directory page and select **Archive** at the bottom. Review existing installations as part of shutting down your app; archiving and uninstalling are separate actions.
-Be careful: uninstalling from a subreddit can remove that installation's stored data and settings. See [Mod resources](./best-practices/mod_resources.md) for the current warning about uninstall data loss.
+**Delete an app or unregister an account:** contact [r/Devvit Modmail](https://www.reddit.com/message/compose/?to=r/Devvit) for help, including if you registered the wrong Reddit account as an app. Uninstalling doesn't unregister the account.
+
+
+
+
+
+How do I get my game featured on Reddit or the Games on Reddit launchpad?
+
+After your game is published and approved, apply through the [Featuring Request Form](https://forms.gle/BeKcqQy8yZEqEmtR6). The Reddit team also scouts games with organic growth.
+
+Before applying, make sure your game has a custom first screen, works on mobile and desktop, is easy for new players to understand, avoids inline scrolling, and has updated in-app catalog assets. Placements are selected by the Reddit team and aren't guaranteed.
+
+Featured games can appear in the Games Feed, Community Drawer, Home Feed, and r/GamesOnReddit. See [Get featured](./launch/feature-guide.mdx) for requirements and distribution tiers.
@@ -515,20 +640,16 @@ Be careful: uninstalling from a subreddit can remove that installation's stored
What is Devvit MCP and how do I set it up?
-Devvit MCP is the bridge used by supported coding tools and agents to search Devvit docs and, in some setups, work with Devvit workflows from your editor. The setup docs live in [Using AI Tools](./ai/ai.md).
-
-If you're configuring Cursor, VS Code Copilot, Claude Code, or Claude Desktop, start there instead of duplicating the JSON in this FAQ. Use the AI tools guide for the exact MCP config and supported tools.
+Devvit MCP connects coding tools and AI assistants to Devvit documentation and development tools. Follow [Using AI Tools](./ai/ai.md) for supported tools and setup instructions, including Cursor, VS Code Copilot, Claude Code, and Claude Desktop.
-
-What should I read next?
+
+Continue building:
- To understand Devvit's built-in Reddit access, read the [Reddit API Overview](../capabilities/server/reddit-api.mdx)
- To learn the CLI commands you'll use most often, read [Devvit CLI](./tools/devvit_cli.mdx)
- To develop against a subreddit and inspect logs, read [Playtest](./tools/playtest.md) and [Logs and Debugging](./tools/logs.md)
-
-
diff --git a/docusaurus.config.ts b/docusaurus.config.ts
index a98b3eee3..91faeed53 100644
--- a/docusaurus.config.ts
+++ b/docusaurus.config.ts
@@ -65,7 +65,10 @@ const config: Config = {
src: `${baseUrl}events.js`,
},
],
- clientModules: ["./src/client/openDetailsForHash.ts"],
+ clientModules: [
+ "./src/client/openDetailsForHash.ts",
+ "./src/client/openKapaForUrl.ts",
+ ],
// GitHub pages deployment config.
// If you aren't using GitHub pages, you don't need these.
diff --git a/src/client/openKapaForUrl.ts b/src/client/openKapaForUrl.ts
new file mode 100644
index 000000000..ca49fe734
--- /dev/null
+++ b/src/client/openKapaForUrl.ts
@@ -0,0 +1,67 @@
+type KapaOpenOptions = {
+ mode: "ai";
+ query: string;
+ submit: false;
+};
+
+type KapaCommand = (command: "open", options: KapaOpenOptions) => void;
+
+declare global {
+ interface Window {
+ Kapa?: KapaCommand | { open: (options: KapaOpenOptions) => void };
+ }
+}
+
+type KapaLocation = {
+ pathname: string;
+ search: string;
+};
+
+let lastOpenedLocation: string | undefined;
+
+function openKapa(query = ""): void {
+ if (!window.Kapa) {
+ // Kapa's preinitialization queue handles links opened before its async script loads.
+ // https://docs.kapa.ai/integrations/website-widget/javascript-api/preinitialize
+ const queuedKapa = function () {
+ queuedKapa.c(arguments);
+ };
+ queuedKapa.q = [] as IArguments[];
+ queuedKapa.c = (args: IArguments) => {
+ queuedKapa.q.push(args);
+ };
+ window.Kapa = queuedKapa;
+ }
+
+ const options: KapaOpenOptions = { mode: "ai", query, submit: false };
+ if ("open" in window.Kapa && typeof window.Kapa.open === "function") {
+ window.Kapa.open(options);
+ } else if (typeof window.Kapa === "function") {
+ window.Kapa("open", options);
+ }
+}
+
+function openKapaForLocation(location: KapaLocation): void {
+ const params = new URLSearchParams(location.search);
+ if (params.get("ask") !== "1") {
+ lastOpenedLocation = undefined;
+ return;
+ }
+
+ const key = `${location.pathname}${location.search}`;
+ if (lastOpenedLocation === key) {
+ return;
+ }
+
+ lastOpenedLocation = key;
+ openKapa(params.get("question") ?? "");
+}
+
+export function onRouteDidUpdate({
+ location,
+}: {
+ location: KapaLocation;
+}): void {
+ // Wait until Docusaurus finishes rendering before opening the modal.
+ openKapaForLocation(location);
+}
diff --git a/versioned_docs/version-0.15/guides/faq.mdx b/versioned_docs/version-0.15/guides/faq.mdx
index c0f6c655e..2ba1be159 100644
--- a/versioned_docs/version-0.15/guides/faq.mdx
+++ b/versioned_docs/version-0.15/guides/faq.mdx
@@ -4,18 +4,30 @@
### Getting Started
+
+
+Should I use Devvit or the Reddit Data API?
+
+Use **Devvit** to build apps that run on Reddit, including games, interactive posts, and moderation tools. Reddit hosts the app, and Devvit manages its Reddit authentication. Start with the [App quickstart](../quickstart/quickstart.md) or [Mod tool quickstart](../quickstart/quickstart-mod-tool.md).
+
+If you're building an **external script, bot, website, or integration** with tools like Python, PRAW, or n8n, follow the [Reddit Data API guidance](https://support.reddithelp.com/hc/en-us/articles/16160319875092-Reddit-Data-API-Wiki). A Devvit login doesn't issue a client ID or client secret for an external application. For a use case that Devvit doesn't support, [request access through Reddit Help](https://support.reddithelp.com/hc/en-us/requests/new?tf_42139884615700=api_request_type_developer_clone&ticket_form_id=14868593862164). Access requires approval under the [Responsible Builder Policy](https://support.reddithelp.com/hc/en-us/articles/42728983564564-Responsible-Builder-Policy).
+
+External Data API access has its own approval process and terms. For commercial data access, use the [commercial access request form](https://support.reddithelp.com/hc/en-us/requests/new?tf_42139884615700=api_request_type_enterprise_clone&ticket_form_id=14868593862164).
+
+
+
Do I need a Reddit API key, client ID, or client secret to build with Devvit?
-No. If you're building a Devvit app, you don't need to create a traditional Reddit app at [`reddit.com/prefs/apps`](https://www.reddit.com/prefs/apps) or manage API keys yourself.
+No. Devvit handles authentication for your app, so you don't need to create an app at [`reddit.com/prefs/apps`](https://www.reddit.com/prefs/apps) or manage API keys yourself.
-Instead, start from the [App quickstart](../quickstart/quickstart.md) or create a project at [developers.reddit.com/new](https://developers.reddit.com/new). During setup, you sign in with your Reddit account and connect it to Reddit developers. Devvit handles authentication for your app.
+Start with the [App quickstart](../quickstart/quickstart.md) or create a project at [developers.reddit.com/new](https://developers.reddit.com/new). During setup, sign in with your Reddit account.
To read or write Reddit content from a Devvit app, enable the Reddit capability described in the [Reddit API Overview](../capabilities/server/reddit-api.mdx).
:::note
-If you're building an external script, bot, or website outside Devvit, that's a different authentication flow from the one documented here.
+For an external script or integration, follow the [Reddit Data API guidance](https://support.reddithelp.com/hc/en-us/articles/16160319875092-Reddit-Data-API-Wiki) to request access. Signing in with Devvit doesn't provide external API credentials.
:::
@@ -24,9 +36,9 @@ If you're building an external script, bot, or website outside Devvit, that's a
Where do I start building a Devvit app?
-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.
+Start with the [App quickstart](../quickstart/quickstart.md) to create a project, connect your Reddit account, and run your first playtest.
-If you already know what you want to build, you can also start with:
+You can also choose a guide for your app or game engine:
- [Quickstart for Games](../quickstart/quickstart.md)
- [Quickstart for Mod Tools](../quickstart/quickstart-mod-tool.md)
@@ -37,7 +49,7 @@ If you already know what you want to build, you can also start with:
-How do I log in, and how do I know I am authenticated?
+How do I log in and check which account I'm using?
Use the CLI to sign in with your Reddit account:
@@ -45,7 +57,7 @@ Use the CLI to sign in with your Reddit account:
npx devvit login
```
-To confirm which account is currently authenticated, run:
+To check which account you're signed in with, run:
```bash
npx devvit whoami
@@ -63,11 +75,9 @@ For command details, see the [`devvit login`](./tools/devvit_cli.mdx#devvit-logi
Can I test locally without uploading to Reddit?
-Not completely. Devvit apps run against Reddit, so the normal development flow uses a playtest subreddit rather than a purely local setup.
-
-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).
+Not completely. Backend calls require Reddit, so use a playtest subreddit to test the full app.
-If you're wondering why a purely local setup isn't enough, the quickstart calls this out directly: backend calls don't work when you test the app only locally.
+Run `npm run dev` from a quickstart project to start a playtest session. See [Playtest](./tools/playtest.md) for more options.
@@ -75,15 +85,15 @@ If you're wondering why a purely local setup isn't enough, the quickstart calls
Why does npm run dev, playtest, upload, or install fail?
-Most development errors fall into a few buckets:
+Check the error message, then try the matching steps:
-- Authentication: make sure you're logged in with `npx devvit login`, then verify the current account with `npx devvit whoami`.
-- Build output mismatch: if Devvit can't find `config.server.entry`, check that your built server file matches the path in `devvit.json`, and that your server build outputs a CommonJS bundle. The best references are [Devvit configuration](../capabilities/devvit-web/devvit_web_configuration.md) and [Vite](./tools/vite.mdx).
-- Config validation: if `devvit.json` complains about invalid fields, extra properties, or settings shapes, validate it against the schema and configuration rules in [Devvit configuration](../capabilities/devvit-web/devvit_web_configuration.md).
-- Fetch or domain errors: if fetch is disabled or a domain is rejected, configure `permissions.http` correctly and review the rules in [HTTP fetch](../capabilities/server/http-fetch.mdx).
-- Runtime failures during playtest or install: use [Playtest](./tools/playtest.md) and [Logs and Debugging](./tools/logs.md) together so you can see the failing endpoint or trigger.
+- **Authentication:** sign in with `npx devvit login`, then check the account with `npx devvit whoami`.
+- **Build output:** if Devvit can't find `config.server.entry`, check that the built server file matches the path in `devvit.json` and that your build outputs a CommonJS bundle. See [Devvit configuration](../capabilities/devvit-web/devvit_web_configuration.md) and [Vite](./tools/vite.mdx).
+- **Configuration:** for invalid fields or extra properties in `devvit.json`, check the schema and rules in [Devvit configuration](../capabilities/devvit-web/devvit_web_configuration.md).
+- **Fetch or domain access:** check `permissions.http` and the requirements in [HTTP fetch](../capabilities/server/http-fetch.mdx).
+- **Runtime errors:** inspect the logs to find the failing endpoint or trigger. See [Playtest](./tools/playtest.md) and [Logs and Debugging](./tools/logs.md).
-One other common gotcha: Devvit projects use `vite build --watch` rather than a normal `vite dev` server. The [Vite guide](./tools/vite.mdx) explains the expected setup.
+For Vite projects, use `vite build --watch` for playtesting. See the [Vite guide](./tools/vite.mdx) for the setup.
@@ -91,19 +101,22 @@ One other common gotcha: Devvit projects use `vite build --watch` rather than a
How do I update the Devvit CLI?
-Prefer updating the project-local CLI dependency instead of relying on a global install. Update `devvit` in your project, then run `npx devvit update app` so your `@devvit` packages match the CLI.
+Update the `devvit` dependency in your project, then run `npx devvit update app` to update your `@devvit` packages to match the CLI.
-For the current commands and workflow, see [Devvit CLI](./tools/devvit_cli.mdx) and the update notes in [Changelog](../changelog.md).
+See [Devvit CLI](./tools/devvit_cli.mdx) for commands and the [Changelog](../changelog.md) for release notes.
+
How do I update my app version?
-Updating the CLI and publishing a new app version are separate steps. Your app version changes when you publish: `npx devvit publish` creates the next launch version, and you can control that with `--bump` or `--version` as described in [Launch your app](./launch/launch-guide.md).
+Run `npx devvit publish` to submit a new app version for review. Use `--bump` or `--version` to control the version number. See [Launch your app](./launch/launch-guide.md) for the publishing steps.
-After that, the subreddit still needs to be on the version you want installed. Publishing a new version doesn't automatically update every subreddit. Use [`devvit install`](./tools/devvit_cli.mdx#devvit-install) or open your app in the [App Directory](https://developers.reddit.com/apps/) and, under **Installed in communities**, use the blue **Update** button for the subreddit that's out of date.
+Publishing doesn't automatically update every subreddit. Once the version is approved, use [`devvit install`](./tools/devvit_cli.mdx#devvit-install) to update a community you moderate. You can also open your app in the [App Directory](https://developers.reddit.com/apps/), find the subreddit under **Installed in communities**, and select **Update**.
+
+Your app version is separate from the Devvit CLI and SDK versions. Updating your development tools doesn't publish or install a new version of your app.
@@ -111,11 +124,11 @@ After that, the subreddit still needs to be on the version you want installed. P
I published and it says a new Devvit version is available. Do I need to upgrade?
-Not necessarily. If you're within 2–3 versions of the current Devvit release, your app will continue working as-is. The version notice is informational — it doesn't mean your app is broken or blocked from publishing.
+Check the [Changelog](../changelog.md) for breaking changes, migration steps, and upgrade requirements for your project's version. The notice means a newer Devvit release is available.
-Staying reasonably current is good practice, though. It gets you access to the latest fixes and capabilities. When you're ready, run `npx devvit update app` to bring your project's `@devvit` packages in line with the latest CLI, then test in playtest before publishing the update.
+To upgrade, update the `devvit` dependency in your project, then run `npx devvit update app` to update your `@devvit` packages to match. Test in playtest before publishing.
-For upgrade steps, see [Devvit CLI](./tools/devvit_cli.mdx) and the [Changelog](../changelog.md).
+See [Devvit CLI](./tools/devvit_cli.mdx) for upgrade commands.
@@ -123,7 +136,7 @@ For upgrade steps, see [Devvit CLI](./tools/devvit_cli.mdx) and the [Changelog](
What is the difference between npx devvit upload and npx devvit publish?
-Use `npx devvit upload` when you want a private uploaded build for yourself, and use `npx devvit publish` when you're ready to submit a version for launch review. In practice, playtest is still the normal dev loop, `upload` is useful for a private installable build, and `publish` is the launch step documented in [Launch your app](./launch/launch-guide.md).
+Use `npx devvit upload` to create a private build you can install. Use `npx devvit publish` to submit a version for launch review. For day-to-day development, use [Playtest](./tools/playtest.md).
For command syntax, see [Devvit CLI](./tools/devvit_cli.mdx). For the review and launch flow, see [Launch your app](./launch/launch-guide.md).
@@ -133,37 +146,47 @@ For command syntax, see [Devvit CLI](./tools/devvit_cli.mdx). For the review and
Why does npx devvit upload say assets uploaded, then fail with "You must be logged in to upload a new app version"?
-This usually means your local Devvit authentication state is stale or corrupted. The asset upload can finish before the CLI fails while creating the new app version.
-
-Reset your local Devvit auth state, then log in again.
+Assets upload separately from the app version, so that step can succeed even when app version creation fails.
-On Windows PowerShell:
+First, refresh your CLI session and check that you're using the expected Reddit account:
-```powershell
+```bash
npx devvit logout
-Remove-Item -Recurse -Force "$env:USERPROFILE\.devvit"
npx devvit login
+npx devvit whoami
```
-On macOS, Linux, or WSL:
+Then retry the upload or playtest. If it still fails, capture the error with `--verbose` and share it with your CLI version and operating system in the [Devvit Discord](https://developers.reddit.com/discord) or [r/Devvit](https://www.reddit.com/r/Devvit). Keep the token stored in `~/.devvit/token` private.
+
+See [Devvit CLI](./tools/devvit_cli.mdx) for authentication and upload options.
+
+
+
+
+
+How do I view live and historical app logs, including timestamps?
+
+Use `npx devvit logs` for an installed app. For example, to show the last two hours of logs with timestamps and continue streaming new logs:
```bash
-npx devvit logout
-rm -rf ~/.devvit
-npx devvit login
+npx devvit logs r/mySubreddit my-app --since 2h --verbose
```
-After logging in, run `npx devvit whoami` to confirm the CLI is using the expected Reddit account, then try `npx devvit upload` again.
+Omit `--since 2h` to start with new logs, or change the interval to values such as `30m` or `1d`. From the app's project directory, you can omit `my-app`. These commands also work in PowerShell.
+
+Logs are limited to 5,000 events or up to seven days. Playtest already streams logs from its test community. Use `console.log()`, `console.info()`, or `console.error()` in server code to create logs; inspect browser developer tools for client-side messages.
+
+See [Logs and Debugging](./tools/logs.md) and the [CLI logs reference](./tools/devvit_cli.mdx#devvit-logs).
-What should I do after playtest when I am ready to launch?
+How do I launch my app after playtesting?
-Before launch, make sure the app is stable across mobile and web, test with multiple accounts, and add the required app [`README.md`](../devvit_rules.md#app-readme-requirements). Then follow the publish flow in [Launch your app](./launch/launch-guide.md).
+Test your app on mobile and web with multiple accounts, and add the required app [`README.md`](../devvit_rules.md#app-readme-requirements). Then follow [Launch your app](./launch/launch-guide.md) to publish.
-If you're just ending a playtest session, remember that the latest playtest install remains in place until you change installs. [Playtest](./tools/playtest.md) and [`devvit install`](./tools/devvit_cli.mdx#devvit-install) cover that handoff.
+Ending a playtest leaves the last playtest build installed in the test subreddit. See [Playtest](./tools/playtest.md) and [`devvit install`](./tools/devvit_cli.mdx#devvit-install) to manage that installation.
@@ -171,11 +194,11 @@ If you're just ending a playtest session, remember that the latest playtest inst
How long does it take to get my app published?
-Most app versions are reviewed within **1–2 business days**. New apps or versions that include higher-risk features may take longer. Features that commonly extend review time:
+Most app versions are reviewed within **1–2 business days**. New apps and versions that need additional review may take longer, including those with:
- **Payments**: apps using the payments capability go through additional policy review.
- **`runAs: 'USER'`**: user action permissions require explicit approval as part of the review.
-- **External fetch domains**: new domain requests are reviewed separately under the same **1–2 business day** target, though requests with policy ambiguity may take longer (see [HTTP Fetch](../capabilities/http-fetch.mdx)).
+- **External fetch domains**: domain requests are reviewed separately, usually within **1–2 business days**. Requests that need policy clarification may take longer. See [HTTP Fetch](../capabilities/http-fetch.mdx).
To keep review moving:
@@ -183,7 +206,7 @@ To keep review moving:
- Ensure your app complies with the [Devvit Rules](../devvit_rules.md).
- If your app uses fetch domains, document them in a "Fetch Domains" section of your [README](../devvit_rules.md#app-readme-requirements).
-If you haven't heard back after a week, reach out in the [Devvit Discord](https://developers.reddit.com/discord) or via [r/Devvit Modmail](https://www.reddit.com/message/compose/?to=r/Devvit). For the full publish flow, see [Launch your app](./launch/launch-guide.md).
+If you haven't heard back after a week, ask in the [Devvit Discord](https://developers.reddit.com/discord) or contact [r/Devvit Modmail](https://www.reddit.com/message/compose/?to=r/Devvit). See [Launch your app](./launch/launch-guide.md) for the full process.
@@ -191,9 +214,9 @@ If you haven't heard back after a week, reach out in the [Devvit Discord](https:
How do I install my app on another subreddit?
-If you moderate the destination subreddit, use [`devvit install`](./tools/devvit_cli.mdx#devvit-install) to install a specific app or version on that community. That's the direct CLI path when you want to move beyond the playtest subreddit or test on another subreddit you control.
+Use [`devvit install`](./tools/devvit_cli.mdx#devvit-install) to install your app in a subreddit you moderate.
-If the goal is broader distribution, follow [Launch your app](./launch/launch-guide.md) so moderators can install the approved app in the appropriate way for its visibility level.
+To make your app available to other moderators, follow [Launch your app](./launch/launch-guide.md) and choose the visibility level that fits your app.
@@ -201,9 +224,11 @@ If the goal is broader distribution, follow [Launch your app](./launch/launch-gu
What is the difference between unlisted and public apps?
-Published apps are unlisted by default. That's usually the right fit for games and single-community tools. If you want your app to appear in the App Directory so any moderator can install it, use `npx devvit publish --public` and follow the listing guidance in [Launch your app](./launch/launch-guide.md).
+Published apps are unlisted by default. Unlisted apps don't appear in the App Directory and work well for games and tools built for a specific community.
+
+To list your app in the App Directory so other moderators can find and install it, use `npx devvit publish --public`. See [Launch your app](./launch/launch-guide.md) for listing requirements.
-All apps submitted for review should look launch-ready: the launch docs require an app [`README.md`](../devvit_rules.md#app-readme-requirements), and game launch guidance expects a custom launch or first screen rather than a rough default experience.
+Before submitting either type for review, add the required app [`README.md`](../devvit_rules.md#app-readme-requirements). Games also need a custom first screen.
@@ -213,7 +238,7 @@ All apps submitted for review should look launch-ready: the launch docs require
What is an interactive post in Devvit?
-An interactive post is a Reddit post created for an app experience rather than a plain text-only post. That means creating the post with `reddit.submitCustomPost()` and defining how it launches through entry points, launch screens, and optional `postData`. See [Interactive posts overview](../capabilities/interactive-posts/interactive_posts_overview.mdx) and [Creating a custom post](../capabilities/creating_custom_post.md).
+An interactive post runs an app experience inside a Reddit post. Create one with `reddit.submitCustomPost()` and configure its views through entry points and launch screens. You can attach data with `postData`. See [Interactive posts overview](../capabilities/interactive-posts/interactive_posts_overview.mdx) and [Creating a custom post](../capabilities/creating_custom_post.md).
@@ -221,7 +246,7 @@ An interactive post is a Reddit post created for an app experience rather than a
Why is my post just text instead of an interactive app post?
-If you call `submitPost()` with normal `text`, you're creating a regular Reddit post. To create an interactive app post, use `submitCustomPost()` and point it at your configured entry point instead. The [Interactive posts overview](../capabilities/interactive-posts/interactive_posts_overview.mdx) is the clearest starting point for that distinction.
+`submitPost()` with `text` creates a regular text post. To create an interactive app post, use `submitCustomPost()` with your configured entry point. See [Interactive posts overview](../capabilities/interactive-posts/interactive_posts_overview.mdx).
@@ -229,22 +254,24 @@ If you call `submitPost()` with normal `text`, you're creating a regular Reddit
What is Devvit Web?
-Devvit Web is the current client/server app model for building Devvit apps with standard web tools like React, Phaser, or Three.js. It's a normal web app plus server endpoints plus `devvit.json` configuration, with Reddit capabilities split between client APIs, server APIs, and config. See [Devvit Web overview](../capabilities/devvit-web/devvit_web_overview.mdx).
+Devvit Web lets you build apps for Reddit with web tools such as React, Phaser, and Three.js. Your app includes a web client, server endpoints, and a `devvit.json` configuration file. Client and server APIs give your app access to Reddit features. See [Devvit Web overview](../capabilities/devvit-web/devvit_web_overview.mdx).
+
-I got a notice that Blocks is deprecated. What do I need to do?
+How do I migrate a Blocks app to Devvit Web?
-Blocks is being replaced by [Devvit Web](../capabilities/devvit-web/devvit_web_overview.mdx). The path depends on how your app is built, but here's what to check first:
+Migrate your app to [Devvit Web](../capabilities/devvit-web/devvit_web_overview.mdx). Start with the parts your app uses:
- **`devvit.yaml`**: If your project still has a `devvit.yaml`, replace it with a `devvit.json`. See [Migrating Blocks/Mod Tools to Devvit Web](./migrate/devvit-singleton.md) for the updated config format and steps.
-- **`Devvit.addCustomPostType()`**: This is the core Blocks API and is deprecated. Move your post rendering to a `client` entry in `devvit.json`, backed by a standard HTML, React, or other web app.
-- **`submitCustomPost()` with `preview`**: The `preview` field (used to render a Blocks component as the post preview) is no longer the right pattern. Use `post.entrypoints` in `devvit.json` to define your inline and expanded views as HTML entry points instead.
+- **`Devvit.addCustomPostType()`**: Replace this deprecated Blocks API with a `client` entry in `devvit.json`, backed by an HTML, React, or other web app.
+- **`submitCustomPost()` with `preview`**: Replace the Blocks preview with HTML entry points. Use `post.entrypoints` in `devvit.json` to define your inline and expanded views.
- **`useWebView`**: If your app launched a web view from inside Blocks, migrate to Devvit Web. See [Migrating from useWebView to Devvit Web](./migrate/inline-web-view.md).
+- **`splash`**: Replace the legacy `submitCustomPost()` splash parameter with HTML entry points and select one using `entry`. See [Migrating from Splash Screens](../capabilities/server/launch_screen_and_entry_points/splash_migration.mdx).
-If your app uses only Blocks without a web view, [Migrating Blocks/Mod Tools to Devvit Web](./migrate/devvit-singleton.md) is the quickest path. If your app has a web view, start with [Migrating from useWebView to Devvit Web](./migrate/inline-web-view.md).
+For a Blocks app without a web view, follow [Migrating Blocks/Mod Tools to Devvit Web](./migrate/devvit-singleton.md). For an app with a web view, follow [Migrating from useWebView to Devvit Web](./migrate/inline-web-view.md).
@@ -252,27 +279,48 @@ If your app uses only Blocks without a web view, [Migrating Blocks/Mod Tools to
Where do I customize the first screen or launch screen?
-For current Devvit Web apps, customize the first screen through your `post.entrypoints` in `devvit.json` and the HTML, CSS, and client code for those entry files. 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).
+Configure `post.entrypoints` in `devvit.json`, then edit the HTML, CSS, and client code for the entry point shown when the post opens.
+
+See [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).
-
-
-Should I use the legacy splash field or HTML launch entry points?
+
+
+
+How do I configure inline and expanded views?
+
+Define the views under `post.entrypoints` in `devvit.json`. For example:
+
+```json title="devvit.json"
+{
+ "post": {
+ "dir": "dist/client",
+ "entrypoints": {
+ "default": { "entry": "src/client/preview.html", "height": "regular" },
+ "game": { "entry": "src/client/game.html" }
+ }
+ }
+}
+```
-:::warning
-**Deprecation notice**: The `splash` parameter in `submitCustomPost()` and Blocks-based launch screens will be deprecated in June. Migrate to HTML-based entry points before then.
-:::
+With the [Devvit Vite plugin](./tools/vite.mdx), these `entry` paths point to source HTML files. Create the post with `entry: 'default'` to show that view inline. The `inline` config field is deprecated; entry points load inline without it.
-Use HTML launch entry points for all new and existing work. The older `splash` parameter is deprecated in favor of entrypoint-based launch screens and `entry` selection in `submitCustomPost()`. If you're updating an older app, start with [Migrating from Splash Screens](../capabilities/server/launch_screen_and_entry_points/splash_migration.mdx).
+To open the game in expanded mode, call `requestExpandedMode()` synchronously from a user click in your client:
-
+```ts
+import { requestExpandedMode } from '@devvit/web/client';
-
-
-How do I handle scrolling and touch gestures in inline vs expanded mode?
+document.querySelector('#play')?.addEventListener('click', (event) => {
+ requestExpandedMode(event, 'game');
+});
+```
+
+In Devvit 0.15, you can also call `requestExpandedMode()` while already expanded to open a different entry point. Expansion must follow a user action; apps can't automatically force fullscreen.
-Treat inline and expanded mode differently. Inline should avoid scroll traps and heavy gesture hijacking so users can still scroll past the post, while expanded is the right place for richer touch interaction and more space.
+Inline mode accepts taps and clicks, and must let users scroll past the post without scroll traps, zoom, or pan interference. Use expanded mode for richer gestures. Store state that both views need on the server, such as in Redis or `postData`, rather than assuming the views share in-memory state.
+
+See [View modes and entry points](../capabilities/server/launch_screen_and_entry_points/view_modes_entry_points.md).
@@ -280,7 +328,7 @@ Treat inline and expanded mode differently. Inline should avoid scroll traps and
How do I add images that ship with my app?
-Put static images in your client `dist/` directory when they should ship with the app version, such as logos, backgrounds, or other bundled art. Reference them directly from your web client (for example via `
`).
+Include static images, such as logos and backgrounds, in your client build output (`dist/`). Reference them from your web client, for example with `
`.
@@ -288,7 +336,7 @@ Put static images in your client `dist/` directory when they should ship with th
How do user image uploads work in Devvit?
-The simplest path is a form field with `type: 'image'`, which returns a Reddit-hosted image URL when the user submits it. For custom flows like screenshots or generated images, send the data to your server and upload it with [Media uploads](../capabilities/server/media-uploads.mdx).
+Use a form field with `type: 'image'` to get a Reddit-hosted image URL when the user submits the form. For screenshots or generated images, send the data to your server and upload it with [Media uploads](../capabilities/server/media-uploads.mdx).
See [Forms](../capabilities/client/forms.mdx) and [Media uploads](../capabilities/server/media-uploads.mdx) for the supported formats and size limits.
@@ -308,23 +356,18 @@ Try compressing the image, reducing dimensions, or retrying from a faster connec
What image URLs can I use in a Devvit app?
-The documented display paths are bundled client assets, Reddit-hosted URLs, and SVG data URLs, depending on the UI surface. If your source image lives somewhere else on the web, don't assume you can hotlink it directly into the UI. Upload it first so Reddit hosts the image, then use the returned URL. See [Media uploads](../capabilities/server/media-uploads.mdx).
+Use bundled client assets, Reddit-hosted URLs, or SVG data URLs, depending on the UI surface. For an image hosted elsewhere, upload it to Reddit first and use the returned URL. See [Media uploads](../capabilities/server/media-uploads.mdx).
-
-What is postData, and when should I use it instead of Redis?
-
-Use `postData` for small shared JSON attached to a single post, like lightweight game state or configuration that all viewers need to read. The docs cap it at 2 KB per post and recommend [Redis](../capabilities/server/redis.mdx) for larger or more persistent data patterns.
-
-
-
-How do I access or update postData?
+How do I use postData, and when should I use Redis?
+
+Use `postData` for small JSON objects shared by everyone viewing a post, such as game configuration. It's limited to 2 KB per post. Use [Redis](../capabilities/server/redis.mdx) for larger datasets or data shared across posts.
-Set `postData` when creating the post, then read it from `context.postData` on either the client or server side. To update it later, fetch the post and call `setPostData()`. The important gotcha is that `setPostData()` replaces the whole object, so merge existing fields first. See [Post data](../capabilities/server/post-data.mdx).
+Set `postData` when creating the post, then read it from `context.postData` on the client or server. To update it, fetch the post and call `setPostData()`. This replaces the whole object, so merge any fields you want to keep before saving. See [Post data](../capabilities/server/post-data.mdx).
@@ -332,9 +375,7 @@ Set `postData` when creating the post, then read it from `context.postData` on e
How do I build a leaderboard with Redis?
-The standard Devvit pattern is to build leaderboards with Redis sorted sets. Use [Redis](../capabilities/server/redis.mdx) for score storage and ranking, use [Scheduler](../capabilities/server/scheduler.mdx) for daily or periodic resets, and prefer realtime updates over constant polling when you need a live leaderboard.
-
-Redis is the right storage layer, but the exact schema depends on whether you need daily, weekly, or all-time rankings. [Redis](../capabilities/server/redis.mdx) is the best starting point.
+Use [Redis sorted sets](../capabilities/server/redis.mdx) to store scores and rank players, and [Scheduler](../capabilities/server/scheduler.mdx) for daily or periodic resets. For a live leaderboard, use realtime updates to send score changes to connected clients.
@@ -342,7 +383,7 @@ Redis is the right storage layer, but the exact schema depends on whether you ne
Can a menu action create a new post?
-Yes. Define the menu item in `devvit.json`, implement the server endpoint it calls, and create the post from that route. The pattern is documented across [Menu actions](../capabilities/client/menu-actions.mdx) and [Interactive posts overview](../capabilities/interactive-posts/interactive_posts_overview.mdx).
+Yes. Define the menu item in `devvit.json`, implement its server endpoint, and create the post from that endpoint. See [Menu actions](../capabilities/client/menu-actions.mdx) and [Interactive posts overview](../capabilities/interactive-posts/interactive_posts_overview.mdx).
@@ -350,7 +391,7 @@ Yes. Define the menu item in `devvit.json`, implement the server endpoint it cal
How do I automate daily or scheduled game posts?
-Use [Scheduler](../capabilities/server/scheduler.mdx) for cron-style recurring jobs or one-off jobs declared in `devvit.json`, then handle the matching `/internal/...` endpoint in your server code. The scheduler docs explain the plumbing; the post creation step still uses the normal Reddit APIs like `submitCustomPost()`.
+Define a recurring or one-time job with [Scheduler](../capabilities/server/scheduler.mdx) in `devvit.json`. In the matching `/internal/...` server endpoint, call `reddit.submitCustomPost()` to create the post.
@@ -358,7 +399,7 @@ Use [Scheduler](../capabilities/server/scheduler.mdx) for cron-style recurring j
How do I post or comment as the user instead of the app?
-Add the required `permissions.reddit.asUser` entries in `devvit.json`, then call the supported Reddit APIs with `runAs: 'USER'`. The main doc for this is [User Actions](../capabilities/server/userActions.mdx), which also explains the review requirements, explicit opt-in rules, and `userGeneratedContent` expectations.
+Add the required `permissions.reddit.asUser` entries in `devvit.json`, then call the supported Reddit APIs with `runAs: 'USER'`. Follow [User Actions](../capabilities/server/userActions.mdx) for review requirements, user opt-in, and `userGeneratedContent` requirements.
@@ -366,7 +407,7 @@ Add the required `permissions.reddit.asUser` entries in `devvit.json`, then call
Why does runAs: 'USER' still post as the app during playtest?
-Before the app version is approved, user actions aren't enabled for everyone. During playtest or other unapproved versions, `runAs: 'USER'` falls back to the app account for most users, while actions taken by the app owner are attributed to the owner's username. After publishing and approval, it operates on behalf of the user for all users. See [User Actions](../capabilities/server/userActions.mdx).
+During playtest or with an unapproved app version, `runAs: 'USER'` uses the app account for most users. Actions taken by the app owner use the owner's username. Once the app version is published and approved, user actions run on behalf of each user. See [User Actions](../capabilities/server/userActions.mdx).
@@ -376,25 +417,55 @@ Before the app version is approved, user actions aren't enabled for everyone. Du
Devvit supports both user flair and post flair through the Reddit API client.
-- For a new post, use the submit options documented in [CommonSubmitPostOptions](../api/redditapi/models/type-aliases/CommonSubmitPostOptions.md), including `flairId` or `flairText`.
+- For a new post, use `flairId` or `flairText` in [CommonSubmitPostOptions](../api/redditapi/models/type-aliases/CommonSubmitPostOptions.md).
- For an existing post, use the flair methods on [RedditClient](../api/redditapi/RedditClient/classes/RedditClient.md), such as `setPostFlair()` and `removePostFlair()`.
- For a user, use `setUserFlair()`, `removeUserFlair()`, or `setUserFlairBatch()` on the same client.
-If you're reading flair back from a post, note that post flair and author flair are different fields. The [Post](../api/redditapi/models/classes/Post.md) model exposes `flair` for the post and `authorFlair` for the post author.
+To apply an existing subreddit flair template when creating an interactive post:
+
+```ts
+import { reddit } from '@devvit/web/server';
+
+const post = await reddit.submitCustomPost({
+ subredditName: 'mySubreddit',
+ title: 'Daily game',
+ entry: 'default',
+ flairId: 'your-flair-template-id',
+});
+```
+
+To preserve existing flair, fetch the subreddit and call `subreddit.getUserFlair({ usernames: ['username'] })` first. Its `users` array includes `flairText` and `flairCssClass`. Combine the values you want to keep with your changes before calling `setUserFlair()`, which replaces the flair. See [getUserFlair](../api/redditapi/models/classes/Subreddit.md#getuserflair).
+
+On the [Post](../api/redditapi/models/classes/Post.md) model, `flair` contains the post's flair and `authorFlair` contains the author's flair.
-If you need to react to flair changes, Devvit documents an [`onPostFlairUpdate`](../capabilities/server/triggers.mdx) trigger for post flair changes. Also note that the [Devvit test tool](./tools/devvit_test.mdx) doesn't yet support the Flair service.
+Use the [`onPostFlairUpdate`](../capabilities/server/triggers.mdx) trigger to react to post flair changes. The [Devvit test tool](./tools/devvit_test.mdx) doesn't yet support the Flair service.
+
-How do I get a user's username or snoovatar?
+How do I get usernames, user avatars, and subreddit icons?
+
+Use `getCurrentUsername()` when you only need the current user's name.
+
+For more profile information, use `getCurrentUser()` from the [Reddit API client](../api/redditapi/RedditClient/classes/RedditClient.md). To get a snoovatar URL, use `reddit.getSnoovatarUrl(username)` or `user.getSnoovatarUrl()` on the [User](../api/redditapi/models/classes/User.md) model.
-If you only need the current user's name, prefer `getCurrentUsername()` over fetching the full user object.
+Some handlers also expose experimental `username` and `snoovatar` fields on [BaseContext](../api/public-api/type-aliases/BaseContext.md).
-If you need more profile information, use `getCurrentUser()` from the [Reddit API client](../api/redditapi/RedditClient/classes/RedditClient.md). To get a snoovatar URL, use `reddit.getSnoovatarUrl(username)` or `user.getSnoovatarUrl()` on the [User](../api/redditapi/models/classes/User.md) model.
+For a subreddit icon, fetch its styles by subreddit ID in your server code:
-Some handlers also expose experimental identity fields like `username` and `snoovatar` on [BaseContext](../api/public-api/type-aliases/BaseContext.md), but the Reddit client methods are the clearest documented path.
+```ts
+import { reddit } from '@devvit/web/server';
+
+const subreddit = await reddit.getCurrentSubreddit();
+const styles = await reddit.getSubredditStyles(subreddit.id);
+const iconUrl = styles.icon;
+```
+
+To look up another community, get its ID with `reddit.getSubredditInfoByName(name)` first. See [getSubredditStyles](../api/redditapi/RedditClient/classes/RedditClient.md#getsubredditstyles) and [SubredditStyles](../api/redditapi/models/type-aliases/SubredditStyles.md#icon).
+
+Icon and snoovatar URLs can be absent, so provide a fallback image or initials.
@@ -402,27 +473,33 @@ Some handlers also expose experimental identity fields like `username` and `snoo
How do I handle external links in Devvit?
-Use Devvit navigation APIs to open links rather than treating this like external fetch. For app navigation, see [Navigation](../capabilities/client/navigation.mdx), which covers `navigateTo` and the confirmation flow for external URLs.
+Use `navigateTo` to open a link. External URLs require user confirmation. See [Navigation](../capabilities/client/navigation.mdx).
-If you actually need remote data or remote media, that's a different path: use [HTTP fetch](../capabilities/server/http-fetch.mdx) for approved server-side fetches, and [Media uploads](../capabilities/server/media-uploads.mdx) when you need a Reddit-hosted media URL.
+To retrieve external data, use [HTTP fetch](../capabilities/server/http-fetch.mdx) from your server. To host an image or video on Reddit, use [Media uploads](../capabilities/server/media-uploads.mdx).
+
+
-How do I update my app profile settings?
+How do I update my app's icon and profile settings?
+
+Set your app's profile icon with `marketingAssets.icon` in `devvit.json`. Use a **1024 × 1024 PNG** and a path relative to the project root:
-App profile settings let you control how your app appears on Reddit via a combination of configuration in `devvit.json` and fields in the Developer Portal.
+```json title="devvit.json"
+{
+ "marketingAssets": {
+ "icon": "assets/icon.png"
+ }
+}
+```
-**Avatar (profile icon)**
-To update your avatar:
+Publish your app and submit it for review. Once approved, the icon appears on your app's Reddit profile. To change it, update the image and submit a new app version for review. Apps support image avatars only; Snoovatars aren't supported.
-1. In your `devvit.json`, set the `marketingAssets.icon` field to the path to your icon from the project root.
-2. When you publish your app and it is approved, this icon is uploaded to your app’s Reddit profile.
-3. To change the icon later, update `marketingAssets.icon` in `devvit.json` and submit the app for a new review.
-4. Only image avatars are supported at this time. Snoovatars are not supported for apps.
+If the profile still shows the old image, check that the version containing the new icon has been approved. See [Marketing assets configuration](../capabilities/devvit-web/devvit_web_configuration.md#marketing-assets).
-You can also edit the display name, about description, and mature flag (18+) fields in the Developer Portal under Developer Settings. Updates will appear in the Developer Portal and on the app's Reddit profile.
+For the display name, about description, and mature flag (18+), open **Developer Settings** in the Developer Portal. These changes appear in the portal and on the app's Reddit profile.
@@ -432,16 +509,18 @@ You can also edit the display name, about description, and mature flag (18+) fie
What are the main storage, payload, and rate limits?
-There's no single limits page today, but these are the most commonly referenced numbers in the docs:
+The main limits are:
-- [Redis](../capabilities/server/redis.mdx): 5 GB max storage per installation, 5 MB max request size, and 40,000 max commands per second.
-- [Devvit Web](../capabilities/devvit-web/devvit_web_overview.mdx): 30 second max request time, 4 MB max payload size, and 10 MB max response size.
+- [Redis](../capabilities/server/redis.mdx): 5 GB of storage per installation, 5 MB per request, and 40,000 commands per second.
+- [Devvit Web](../capabilities/devvit-web/devvit_web_overview.mdx): 30 seconds per request, a 4 MB request payload, and a 10 MB response.
- [Post data](../capabilities/server/post-data.mdx): 2 KB per post.
- [Settings and secrets](../capabilities/server/settings-and-secrets.mdx): 2 KB per setting value.
- [Realtime](../capabilities/realtime/overview.md): 1 MB maximum message payload and 100 messages per second per installation.
- [Scheduler](../capabilities/server/scheduler.mdx): up to 10 live recurring actions per installation, plus `runJob()` limits documented on that page.
-If you need data to survive app updates, don't rely on browser `localStorage`. The [Devvit Web overview](../capabilities/devvit-web/devvit_web_overview.mdx) recommends Redis for persistent storage across versions.
+**Redis limits apply to each installation of your app in a subreddit.** Posts and users in that installation share its storage allowance. Each subreddit installation has a separate Redis namespace and can't read another installation's keys. See [Redis data storage](../capabilities/server/redis.mdx#data-storage).
+
+Use Redis for data that needs to survive app updates. See the [Devvit Web overview](../capabilities/devvit-web/devvit_web_overview.mdx) for persistence guidance.
@@ -449,39 +528,64 @@ If you need data to survive app updates, don't rely on browser `localStorage`. T
How long does it take to get my domain approved?
-Domain requests are reviewed separately from app publishing. Most domain requests are reviewed within **1–2 business days**, though requests with policy ambiguity may take longer. If your app was approved but a requested fetch domain wasn't yet granted, the domain review may still be in progress.
+Most domain requests are reviewed within **1–2 business days**. Requests that need policy clarification may take longer. Domain review is separate from app review, so your app can be approved while a domain request is still in progress.
-To make approval go smoothly:
+When requesting a domain:
-- Use exact hostnames only — no wildcards (`*.example.com`), no protocols (`https://`), and no paths (`api.example.com/webhooks`).
+- Use exact hostnames, such as `api.example.com`. Omit wildcards, protocols, and paths.
- Add a "Fetch Domains" section to your app [`README.md`](../devvit_rules.md#app-readme-requirements) listing each domain and explaining why you need it. The expected format is documented in [HTTP Fetch](../capabilities/http-fetch.mdx).
- Include links to your Terms and Conditions and Privacy Policy in your app details form.
-Before submitting, check the [global fetch allowlist](../capabilities/http-fetch.mdx#global-fetch-allowlist) — if your domain is already listed there, no separate request is needed. Personal domains (e.g., `personaldomain.com`) aren't approved.
+Check the [global fetch allowlist](../capabilities/http-fetch.mdx#global-fetch-allowlist) first. Domains on that list don't need a separate request. Personal domains, such as `personaldomain.com`, aren't approved.
+
-What screen sizes should I design for?
+How do I set my post height, and what dimensions should I design for?
+
+Set the inline height per entry point in `devvit.json`, for example `"height": "regular"`. The [configuration schema](https://developers.reddit.com/schema/config-file.v1.json) accepts the named heights `short`, `regular`, and `tall`. Config values use lowercase; the custom-post `styles.height` API uses enum values such as `REGULAR` and `TALL`.
-There's no single published pixel size for every device or view mode. Build responsive layouts and test them across the views supported by the [UI Simulator](./tools/ui_simulator.mdx): mobile, desktop, and fullscreen.
+The [custom post style presets](../capabilities/creating_custom_post.md#custom-post-styles) are:
-Inline and expanded mode behave differently: expanded is the larger experience, with more room for rich interaction, while inline should stay lightweight and feed-friendly.
+| Preset | Height |
+| --- | --- |
+| `REGULAR` | 320 px |
+| `TALL` | 512 px |
-Start with mobile-first assumptions and validate in the simulator before hard-coding dimensions. The best references are [View modes and entry points](../capabilities/server/launch_screen_and_entry_points/view_modes_entry_points.md), [Launch screen customization](../capabilities/server/launch_screen_and_entry_points/launch_screen_customization.md), and [UI Simulator](./tools/ui_simulator.mdx).
+Width varies with the viewport, approximately 288–880 px. Expanded mode uses a larger modal on web or fullscreen on mobile, so build responsive layouts and test mobile, desktop, and fullscreen in the [UI Simulator](./tools/ui_simulator.mdx).
+
+For an exact pixel height, use the **experimental** `post.entrypoints..styles.height` setting. It accepts an integer from 72 to 512. For example:
+
+```json title="devvit.json"
+{
+ "post": {
+ "dir": "dist/client",
+ "entrypoints": {
+ "default": {
+ "entry": "src/client/preview.html",
+ "styles": { "height": 180 }
+ }
+ }
+ }
+}
+```
+
+Use an SDK version that supports this experimental setting and validate your config against its schema. This setting is ignored in fullscreen. See [View modes and entry points](../capabilities/server/launch_screen_and_entry_points/view_modes_entry_points.md) for the view configuration.
+
-Can I build NSFW games or apps with Devvit?
+Can my app use NSFW content, and why are NSFW listings empty or showNsfw false?
-There's no separate NSFW platform guide in these docs, so the main source of truth is [Devvit Rules](../devvit_rules.md) plus Reddit's linked platform policies.
+For mature content, follow the [Devvit Rules](../devvit_rules.md), including labeling and age-gating requirements. Uploaded media also goes through the safety checks described in [Media uploads](../capabilities/server/media-uploads.mdx).
-The rules explicitly require labels or age-gating before exposing users to graphic, sexually explicit, or otherwise mature content. Static assets and uploaded media are also subject to the same safety checks and policy review described in [Media uploads](../capabilities/server/media-uploads.mdx).
+The [User model](../api/redditapi/models/classes/User.md#shownsfw) has two separate fields: `showNsfw` indicates whether the user is over 18 and wants to see NSFW content, while `nsfw` indicates whether the profile is marked NSFW. `showNsfw` is read-only. Don't rely on a mature profile label or your personal account's viewing preferences to grant the app access to NSFW content.
-If your app idea depends on adult content or NSFW communities, review those rules first and get clarification in the [Devvit Discord](https://developers.reddit.com/discord) before you ship.
+If a listing unexpectedly returns no posts, try the same API call in a public SFW community. Then contact [r/Devvit Modmail](https://www.reddit.com/message/compose/?to=r/Devvit) with your app name and version, SDK version, target community, API method, and a small example that reproduces the issue. The team can check the access available to your app.
@@ -500,14 +604,35 @@ For help from the Devvit team and community:
+
-How do I uninstall or remove a Devvit app from a subreddit?
+How do I uninstall, delete, or archive an app, or unregister an app account?
+
+**Remove an installation from a subreddit:** use `npx devvit list installs` to inspect your installations, then uninstall from a community you moderate:
+
+```bash
+npx devvit uninstall r/mySubreddit my-app
+```
+
+You can also open the app in the [App Directory](https://developers.reddit.com/apps/), select the subreddit under **Installed in communities**, and choose **Remove from community**. See the [CLI reference](./tools/devvit_cli.mdx#devvit-uninstall).
-Use the CLI to inspect installs and uninstall from a subreddit. The current docs point to `list installs` and `uninstall` in [Devvit CLI](./tools/devvit_cli.mdx).
+Uninstalling can remove the installation's stored data and settings. See [Mod resources](./best-practices/mod_resources.md) before removing an installation.
-There's also a manual path in the [App Directory](https://developers.reddit.com/apps/). Open your app there, then either use **Installed in communities** to select a subreddit and choose **Remove from community**, or scroll to the bottom of the app page and use **Archive** if you want to archive the app itself.
+**Archive the app:** open its App Directory page and select **Archive** at the bottom. Review existing installations as part of shutting down your app; archiving and uninstalling are separate actions.
-Be careful: uninstalling from a subreddit can remove that installation's stored data and settings. See [Mod resources](./best-practices/mod_resources.md) for the current warning about uninstall data loss.
+**Delete an app or unregister an account:** contact [r/Devvit Modmail](https://www.reddit.com/message/compose/?to=r/Devvit) for help, including if you registered the wrong Reddit account as an app. Uninstalling doesn't unregister the account.
+
+
+
+
+
+How do I get my game featured on Reddit or the Games on Reddit launchpad?
+
+After your game is published and approved, apply through the [Featuring Request Form](https://forms.gle/BeKcqQy8yZEqEmtR6). The Reddit team also scouts games with organic growth.
+
+Before applying, make sure your game has a custom first screen, works on mobile and desktop, is easy for new players to understand, avoids inline scrolling, and has updated in-app catalog assets. Placements are selected by the Reddit team and aren't guaranteed.
+
+Featured games can appear in the Games Feed, Community Drawer, Home Feed, and r/GamesOnReddit. See [Get featured](./launch/feature-guide.mdx) for requirements and distribution tiers.
@@ -515,20 +640,16 @@ Be careful: uninstalling from a subreddit can remove that installation's stored
What is Devvit MCP and how do I set it up?
-Devvit MCP is the bridge used by supported coding tools and agents to search Devvit docs and, in some setups, work with Devvit workflows from your editor. The setup docs live in [Using AI Tools](./ai/ai.md).
-
-If you're configuring Cursor, VS Code Copilot, Claude Code, or Claude Desktop, start there instead of duplicating the JSON in this FAQ. Use the AI tools guide for the exact MCP config and supported tools.
+Devvit MCP connects coding tools and AI assistants to Devvit documentation and development tools. Follow [Using AI Tools](./ai/ai.md) for supported tools and setup instructions, including Cursor, VS Code Copilot, Claude Code, and Claude Desktop.
-
-What should I read next?
+
+Continue building:
- To understand Devvit's built-in Reddit access, read the [Reddit API Overview](../capabilities/server/reddit-api.mdx)
- To learn the CLI commands you'll use most often, read [Devvit CLI](./tools/devvit_cli.mdx)
- To develop against a subreddit and inspect logs, read [Playtest](./tools/playtest.md) and [Logs and Debugging](./tools/logs.md)
-
-