Skip to main content

Post data

You can attach small amounts of data (2KB) to a post when creating it and update this data using the postData capability. This enables dynamic, stateful experiences available on posts without a server call. Post data is scoped to the post, not users.

Post data is useful for storing game state, scores, or any other information that needs to persist with the post and be shared across all users.

Post data is set when you submitPost and apps can access from the context object or do a server side call to update the post data on a Post object. For larger data, use redis.

note

Post data is sent to the client. Never store secrets or sensitive information.

Creating posts with data

When creating a post, include the postData parameter with your custom data object.

server/index.ts
import { context, reddit } from '@devvit/web/server';
import type { JsonObject } from '@devvit/web/shared';

type CreatePostResponse = {
postId: string;
message: string;
};

type ErrorResponse = {
error: string;
};

app.post('/api/create-post', async (c) => {
const { subredditName } = context;

if (!subredditName) {
return c.json<ErrorResponse>({ error: 'Subreddit name is required' }, 400);
}

const postData: JsonObject = {
challengeNumber: 42,
totalGuesses: 0,
gameState: 'active',
pixels: [
[0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 2, 2, 1, 0, 0, 0, 0],
[0, 0, 0, 2, 2, 1, 1, 1, 0, 0, 0],
[0, 0, 2, 2, 1, 1, 1, 1, 1, 0, 0],
[0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
[1, 1, 2, 2, 2, 2, 2, 2, 2, 1, 1],
[0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
[0, 0, 2, 2, 1, 1, 1, 1, 1, 0, 0],
[0, 0, 0, 2, 2, 1, 1, 1, 0, 0, 0],
[0, 0, 0, 0, 2, 2, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0]
],
};

const post = await reddit.submitCustomPost({
subredditName,
title: 'Post with custom data',
entry: 'default',
postData,
});

return c.json<CreatePostResponse>({
postId: post.id,
message: 'Post created successfully',
});
});

Updating post data

To update post data after creation, fetch the post and use the setPostData() method.

server/index.ts
import { context, reddit } from '@devvit/web/server';
import type { JsonObject } from '@devvit/web/shared';

type UpdatePostDataRequest = {
favoriteColor?: string;
username?: string;
};

type UpdatePostDataResponse = {
success: true;
message: string;
};

type ErrorResponse = {
error: string;
};

app.post('/api/update-post-data', async (c) => {
const { postId } = context;
const { favoriteColor, username } = await c.req.json<UpdatePostDataRequest>();

if (!postId) {
return c.json<ErrorResponse>({ error: 'Post ID is required' }, 400);
}

try {
const post = await reddit.getPostById(postId);

// Get existing post data to merge with updates
const currentData = (context.postData || {}) as JsonObject;

await post.setPostData({
...currentData,
favoriteColor: favoriteColor || 'unknown',
lastUpdatedBy: username || 'anonymous',
lastUpdatedAt: new Date().toISOString(),
});

return c.json<UpdatePostDataResponse>({
success: true,
message: 'Post data updated successfully',
});
} catch (error) {
console.error('Error updating post data:', error);
return c.json<ErrorResponse>({ error: 'Failed to update post data' }, 500);
}
});
warning

setPostData() replaces the entire post data object. To update specific fields while preserving others, merge the existing data with your updates.

Accessing post data

Post data is available through context.postData in both client and server contexts.

client/index.tsx
import { context } from '@devvit/web/client';

export const App = () => {
return (
<div>
<text className='mt-1 font-bold'>Post Data:</text>
<text>{JSON.stringify(context.postData, null, 2) ?? 'undefined'}</text>
</div>
);
}

Limitations

Post data supports:

  • JSON-serializable objects only
  • Maximum size of 2KB
  • Data persists with the post lifecycle (deleted when post is deleted)
  • Updates to post data don't trigger automatic re-renders. Implement polling or refresh mechanisms as needed