Using Astro Image Optimization Benefits with Tina CMS Cloud in Production build
Tags: astro, javascript, jamstack
Published: 2024-06-16 17:15:30

## Problem Statement
In production, the benefits of image optimization using Astro's Image/Picture component are lost when integrating with Tina CMS and Tina Cloud. However, I have found a workaround to resolve this issue. Whether this workaround is the best or a good fit for client websites remains uncertain, but here are the details. For further context, you can read the github discussion [here](https://github.com/tinacms/tinacms/discussions/4035#discussioncomment-6264333).

## Preface
Typically, you have a markdown file with an image path pointing to a locally based image, like so:

``` markdown
imgSrc: /src/assets/img/logo.png
...
```

To leverage the image optimization benefits of the Astro Image component, such as generating multiple versions of an image based on device density, you would use dynamic image imports as described [in astro docs](https://docs.astro.build/en/recipes/dynamically-importing-images/). Everything works perfectly in development mode when you run npm run `"tinacms dev -c \"astro dev\"",`. [Tina CLI commands](https://tina.io/docs/cli-overview/) But for clarity here an example of importing images dynamically. 

``` javascript
---
import type { ImageMetadata } from "astro";
import { Image } from "astro:assets";

interface Props {
  imgSrc: string;
}

const { imgSrc } = Astro.props;

const images = import.meta.glob<{ default: ImageMetadata }>("/src/assets/img/*.{jpeg,jpg,png,gif}");

if (!images[imgSrc]) {
  throw new Error(`"${imgSrc}" does not exist in glob: "src/assets/img/*.{jpeg,jpg,png,gif}"`);
}

---

<Image
  width="70"
  height="70"
  src={images[imgSrc]()}
  alt="test image"
  densities={[1.5, 2]}
  loading="lazy"
/>

```
## The Production Issue
In production, Tina CMS typically retrieves its media from its own CDN server (e.g., https://assets.tina.io/image). This setup conflicts with Astro's automatic image optimization and the associated glob pattern.

The function tries to search for the image in the local path. This works in development mode, but in production, the `imgSrc` returned from the markdown file is no longer a local string. Instead, it returns a URL like https://assets.tina.io/image, causing the search function aka glob function to fail and resulting in a build error.

For more information, refer to the github discussion [here](https://github.com/tinacms/tinacms/discussions/4035#discussioncomment-6264333).

## Workaround for Using Image Optimization
To still leverage Astro's image optimization in production, you need to adapt the build script:

## Modified Build Script
The build script must be updated to:

```json
"scripts": {
  "build": "tinacms build --local -c \"astro build\""
}
```

However, be aware that dynamically fetching data will no longer work as expected. For example, querying dynamic data using Tina's client in for example a Date component will not working properly.

## Example script of my dynamically data fetches

```javascript
<script>
        import { formatMarkdownUrl, formatDateString } from "../utils/format";

        document.addEventListener("DOMContentLoaded", async () => {
            try {
                const { client } = await import(
                    "../../tina/__generated__/client"
                );

                async function getLiveDatesResponse() {
                    try {
                        const response =
                            await client.queries.live_dateConnection({
                                sort: "date",
                            });
                        return response;
                    } catch (error) {
                        console.error(
                            error,
                        );
                        return null;
                    }
                }

            }
        })
</script>
```

## Conclusion
This workaround allows you to leverage Astro's image optimization benefits in production while using Tina CMS and Tina Cloud. However, it introduces limitations in dynamically fetching data, which may not be suitable for all use cases. Evaluate whether this approach fits your project's requirements and constraints.

For further reading and to join the discussion, check out the GitHub discussion.