Storing Media with Content
Note: This approach is not officially supported by the core team. It reflects how some teams are currently achieving grouped content and media. Use at your own discretion.
By default, TinaCMS expects:
- Markdown files in a dedicated content directory, e.g.
content/ - Images in a dedicated static directory, e.g.
public/uploads/
This setup works in many modern web frameworks (like Next.js, Astro, etc.) where static assets are served from a public directory, but it breaks co-location ā your content and related assets live in different locations.
This adds friction when managing, duplicating, or migrating content.
Solution: Move the content to the media folder
The current way to solve the issue is to store both Markdown and static assets in public/uploads.
Say you want to build a blog with posts, your file structure for the content would then look like this:
public/āāā uploads/āāā posts/āāā post-a/ā āāā index.mdā āāā image.png
Note:public/uploadsis the default Media folder, you can change it to be whatever suits your project.
See this for more information: Repo-based Media
The only thing required to make this work is to update the path in your Collection file to point to the Media folder.
//tina/collections/post.tsconst Post: Collection = {label: "Posts",name: "post",path: "public/uploads/posts",fields: [//...],//...};
Considerations
- Markdown files live inside the Media folder - this is unconventional
- Content is publicly readable (like any other static assets), so don't store sensitive information
- Every file in
publicgets copied to your build output - Could impact build performance, potentially increasing build times
Conclusion
For projects using TinaCMS with modern frontend frameworks, keeping Markdown and media together simplifies everything from authoring to deployment.
ā Benefits:
- No extra dev work
- Minimal config
- Media Manager works as expected
- Clean structure and great developer experience
If you want to see other viable options, have a look at this video:
Got a different setup that works for you? Let us know!