diff --git a/docs/src/app/(docs)/concepts/theming/page.mdx b/docs/src/app/(docs)/concepts/theming/page.mdx
index 7537241a6c..bb104af00b 100644
--- a/docs/src/app/(docs)/concepts/theming/page.mdx
+++ b/docs/src/app/(docs)/concepts/theming/page.mdx
@@ -493,6 +493,32 @@ type UploadDropzoneProps = {
};
```
+Each `ContentField` can be a fixed value or a callback. Callback fields receive
+the current component state, so you can change the copy for loading, uploading,
+dragging, and selected-file states. `UploadDropzone` callbacks also receive
+`isDragActive`; both components expose `ready`, `isUploading`, `uploadProgress`,
+`fileTypes`, and `files` where applicable.
+
+For example, a dropzone can show different translated labels while it is
+preparing, while the user is dragging files over it, and after files have been
+selected:
+
+```jsx
+
+```
+
When you take over the `content` of an element, you get full responsibility to
control the different states of the component. For example, if you customize
@@ -528,3 +554,37 @@ type UploadDropzoneProps = {
+
+### Internationalization
+
+UploadThing does not bundle translations for its components. Instead, use the
+`content` prop to provide copy from your application's translation catalog. A
+content callback receives the component state, so translated content can still
+show loading and upload progress:
+
+```tsx
+const french = {
+ loading: "Chargement...",
+ chooseFiles: "Choisir des fichiers",
+ uploading: "Téléversement",
+ allowedContent: "Images jusqu'à 4 Mo",
+};
+
+;
+```
+
+The same approach works with `UploadDropzone`. Supply translated content for its
+`label`, `button`, and `allowedContent` fields, and keep any state-specific copy
+in callbacks.