While migrating my portfolio from Hugo to Astro, I ran into some unexpected issues when integrating TinaCMS. It took me a couple of days to sort everything out, so Iām sharing the solution here ā hopefully it saves someone some time.
1ļøā£ Installing and initializing TinaCMS
To connect TinaCMS to an Astro project, install the required dependencies and initialize Tina:
npm install tina-cloud-cli tinacms @tinacms/cli
npx tina init
package.json
"scripts": {
"dev": "tinacms dev -c \"astro dev\"",
"build": "tinacms build && astro build",
"preview": "astro preview",
"astro": "astro"
}
2ļøā£ Checking Tina configuration (tina/config.ts)
Make sure that:
- the Tina admin app is built into the public folder
- images uploaded via Tina are stored in public/img
- /public is never used in URLs
Correct configuration:
build: {
outputFolder: "admin",
publicFolder: "public",
},
media: {
tina: {
mediaRoot: "img",
publicFolder: "public",
},
},
As a result:
- files physically live in public/img
- image paths in content use /img/filename.jpg
3ļøā£ Using images in Astro
For images added via TinaCMS, you must not use <Image /> from astro:assets.
Tina stores image paths as strings, while astro:assets expects local assets from src/, which causes build errors.
ā Incorrect:
<Image src={heroImage} />
ā Correct:
<img src={heroImage} alt="" />
4ļøā£ Checking content.config.ts
In your content schema, the image field must be defined as a string, not as image() from astro:content.
ā Incorrect:
heroImage: image(),
ā Correct:
heroImage: z.string().optional(),
Example of a correct collection:
const blog = defineCollection({
loader: glob({ base: "./src/content/blog", pattern: "**/*.{md,mdx}" }),
schema: () =>
z.object({
title: z.string(),
description: z.string(),
pubDate: z.coerce.date(),
heroImage: z.string().optional(),
}),
});
š§ Key takeaways
- public/ is not part of the URL
- TinaCMS images ā public/img
- In content ā only strings (/img/ā¦)
- In templates ā regular <img>
- astro:assets and TinaCMS are not compatible for images
Anastasiia Berest
Senior Web UI Engineer