Build a basic Astro component and add it to Sitecore JSS Headless Site

First of all, thanks to Anton Tishchenko for building such a wonderful Astro JSS framework. Now, wish to convey that I don't have much background with Astro but by just browsing this vast resource named internet and the Astro JSS examples scaffold-ed in the framework, I've managed to write this first and basic post that involves building a simple Astro JSS component from scratch. 

Pre-requisites

- Setup local Docker instance and client-side application 

Note that astro jss supports only integrated mode at this point. In other words, the client-side doesn't run in disconnected mode.

Context

For this exercise, I randomly picked up a site from Astro examples. In that site, the Skills component seemed perfect to replicate as a basic component in Sitecore. 

I decided to do this in two iterations. The first iteration was to bring the component to display in Experience Editor(XPE) without setting up any CMS template(s) or content and then in the second iteration, I add the Sitecore template and content so that the component works dynamically.

1. Iteration-1

Now, as with anything in Sitecore, two sides to setup the rendering: Client-side and Server-side

1.1 Client-side Setup

This is basically the html/css/ts code. So, you might need a FED for help if building a new component.

1. As a first step, I copied over the markup from Skills.astro and placed it in my file system in this location without changing the name of the file: 

C:\jss-astro\jss-astro-public\astro-sitecore-jss\packages\astro-sitecore-jss-sample\src\components\Skills.astro

Just for reference, this is how my copied Skills.astro looks in my file system:


2. Since the style section references the global.css styles and there is also a reference to it on top of the Skills.astro file, i copied over the global.css file from the Astro examples file system to mine under the same styles folder:


3. I also copied over Icon.astro and IconPaths.ts to the same location as Skills.astro:


That's it, the client-side is ready for now. Next is to link the client-side to server-side:

1.2 Server-side Setup

This is the usual Sitecore way of creating a rendering definition and adding it to the placeholder. Also, most the heavy-lifting is done by the layout file - C:\jss-astro\jss-astro-public\astro-sitecore-jss\packages\astro-sitecore-jss-sample\src\layouts\JssLayout.astro

Since the intent of the post is to build the component, I'm just using the oob index page to add the component.

4. Under /sitecore/layout/Renderings/Project/Headless/Astro, create a JSON Rendering and name is Skills:


5. At this point, if  you open Home page in Experience Editor and try to add a rendering, this is what you should see:


6. Since jss-main is the main placeholder, Skills rendering must be added to that placeholder and ensure to Click Unprotect item to enable controls:


jss-main placeholder:


7. At this point, Skills rendering must be available in XPE toolbox:


8. Now, if you select the rendering, the rendering must be added to the placeholder in XPE:


2. Iteration-2

In this iteration, I add the template and content to give some power to the content editors!

2.1 Server-side Setup

9. First of all, Create two Sitecore data templates:

i) Skill with following fields:



ii) Skills with skillset multilist:



As specified in the above multi-list, setup Source content in the content tree in the relevant location:



10. Next, under /sitecore/content/Headless/Astro/home/Page Data, setup the Skills list:



As of now, the content is ready, next process is to wire the template/content to the rendering markup.

At this point, if you execute the dotnet sitecore ser pull command in PS, all Sitecore items (inc. content) seem to be pulled fine to the file system:



2.2 Client-side Setup

 For this part, I used the Styleguide-FieldUsage-ContentList.astro as example, this is present under - C:\jss-astro\jss-astro-public\astro-sitecore-jss\packages\astro-sitecore-jss-sample\src\components\fields

11. Main change in the Skills.astro file is the inclusion of Sitecore template fields:

---
import '../styles/global.css';
import { RichText } from '@astro-sitecore-jss/astro-sitecore-jss';
import { Text } from '@astro-sitecore-jss/astro-sitecore-jss';
import { Image } from '@astro-sitecore-jss/astro-sitecore-jss';

const { fields } = Astro.props.route;
---

<section class="box skills">
{fields.skillset && fields.skillset.map((listItem: any) => (
<div class="stack gap-2 lg:gap-4">
<Image field={listItem.fields.icon} height="40" width="40" />
<Text tag="h2"  field={listItem.fields.title} />        
<RichText tag="p" field={listItem.fields.description} />  
</div>
  ))}
</section>

Although there is a lot of Astro documentation, with my basic understanding of Astro, the most important aspects in the above code are:

a. Imports and external integration code is written between these 3 hyphen-borders:
---

---

b. The Astro.props.route is the most important line since it integrates this astro file to Sitecore side template

c. Since the multilist is named skillset, each individual item is mapped as listItem and then the fields are accessible thereafter

12. With that basic setup, you should be able to see the end-result in XPE:



13. The head, with some original content too so that this component looks genuine!


I just did a dotnet sitecore ser pull one last time and did a Github Commit

Astro JSS verdict

- For a developer who doesn't have any front-end development skills, Astro seems quick and easy to start with some basic html and css skills, also with some house-keeping, css for each component can be moved to their own files

- The Sitecore-side development skills don't change much - template / inheritance etc.

- The Astro JSS SDK examples are really useful in integrating the Astro-side to Sitecore

- Icing on the cake is XPE-support

- Like any JSS framework, no Sitecore publishing needed, just save the item and reload the rendering

- Like any JSS framework, hot reload of rendering on save of astro file

- Easy way to import a child component into a parent component and passing values as attributes aka props: E.g., Skills component can nest and invoke a Skill component

Issues and resolution

1. While trying to open the home page via XPE, received the following message in the browser:

the remote name could not be resolved: 'host.docker.internal' 

Tried various gimmicks like executing down, clean PS scripts and up.ps1 but what worked finally is executing  docker system prune -a followed by up.ps1 

2. While trying to access the (home) page via XPE, if you receive the following message in the browser, one of the reasons is your client instance is not running. Use the client-side application read me page to setup the instance first and then access the page via XPE

Unable to connect to remote server

Comments