Tailwind Logo

Creating components for the Hero area (Part 2)

Next.js

Published: 2022-03-18

In the last issue, we created and placed a new component, but it still looks like a Tailwind CSS design with just normal HTML displayed. This time we want to change the appearance a bit and also change a few attributes of the content.

Change content type

Previously, Single-Line Text was applied to all items when they were created.

Scaffold18.png

To make it a little easier to use, we will change the content type. First, change the "image" item to "image" on the administration page.

Scaffold19.png

In addition, specify an image (in this case, an image from Content Hub).

Scaffold20.png

Now that we have changed the content type, we can handle images in the Next.js project that specifies the layout. change the content type of image to CommonFieldTypes.Image.

TypeScript
export default function Hero(manifest: Manifest): void {
  manifest.addComponent({
    name: 'Hero',
    icon: SitecoreIcon.DocumentTag,
    fields: [
      { name: 'title1', type: CommonFieldTypes.SingleLineText },
      { name: 'title2', type: CommonFieldTypes.SingleLineText },
      { name: 'text', type: CommonFieldTypes.SingleLineText },
      { name: 'image', type: CommonFieldTypes.Image },
    ],
  });
}

If you are using Visual Studio Code, it is very convenient because it shows you the available types in CommonFieldTypes as candidates.

Scaffold21.png

Next, update the file for display. The changes include adding Image to @sitecore-jss/sitecore-jss-nextjs import and changing two definitions related to image.

TypeScript
import {
  Text,
  Field,
  Image,
  ImageField,
  withDatasourceCheck,
} from '@sitecore-jss/sitecore-jss-nextjs';
import { StyleguideComponentProps } from 'lib/component-props';

type HeroProps = StyleguideComponentProps & {
  fields: {
    title1: Field<string>;
    title2: Field<string>;
    text: Field<string>;
    image: ImageField;
  };
};

const Hero = (props: HeroProps): JSX.Element => (
  return (
    <div>
      <p>Hero Component</p>
      <Text tag="h2" className="text-2xl font-bold" field={props.fields.title1} />
      <Text tag="h3" className="text-1xl font-bold" field={props.fields.title2} />
      <Text field={props.fields.text} />
      <Image media={props.fields.image} />
    </div>
  );
);

export default withDatasourceCheck()<HeroProps>(Hero);

When the changes have been made, run the command and you will see the following. The image data modified by Sitecore is now displayed in the place where the text originally appeared.

Scaffold22.png

Clean and tidy appearance

To make it look a little nicer, we will use the Tailwind CSS sample code. The following is the section with the necessary code.

TypeScript
import {
  Text,
  Field,
  Image,
  ImageField,
  withDatasourceCheck,
} from '@sitecore-jss/sitecore-jss-nextjs';
import { StyleguideComponentProps } from 'lib/component-props';

type HeroProps = StyleguideComponentProps & {
  fields: {
    title1: Field<string>;
    title2: Field<string>;
    text: Field<string>;
    image: ImageField;
  };
};

const Hero = (props: HeroProps): JSX.Element => {
  return (
    <div className="relative bg-gray-50">
      <main className="lg:relative">
        <div className="mx-auto max-w-7xl w-full pt-16 pb-20 text-center lg:py-48 lg:text-left">
          <div className="px-4 lg:w-1/2 sm:px-8 xl:pr-16">
            <h1 className="text-4xl tracking-tight font-extrabold text-gray-900 sm:text-5xl md:text-6xl lg:text-5xl xl:text-6xl">
              <span className="block xl:inline">
                <Text field={props.fields.title1} />
              </span>{' '}
              <span className="block text-indigo-600 xl:inline">
                <Text field={props.fields.title2} />
              </span>
            </h1>
            <p className="mt-3 max-w-md mx-auto text-lg text-gray-500 sm:text-xl md:mt-5 md:max-w-3xl">
              <Text field={props.fields.text} />
            </p>
            <div className="mt-10 sm:flex sm:justify-center lg:justify-start">
              <div className="rounded-md shadow">
                <a
                  href="#"
                  className="w-full flex items-center justify-center px-8 py-3 border border-transparent text-base font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 md:py-4 md:text-lg md:px-10"
                >
                  はじめに
                </a>
              </div>
              <div className="mt-3 rounded-md shadow sm:mt-0 sm:ml-3">
                <a
                  href="#"
                  className="w-full flex items-center justify-center px-8 py-3 border border-transparent text-base font-medium rounded-md text-indigo-600 bg-white hover:bg-gray-50 md:py-4 md:text-lg md:px-10"
                >
                  ライブデモ
                </a>
              </div>
            </div>
          </div>
        </div>
        <div className="relative w-full h-64 sm:h-72 md:h-96 lg:absolute lg:inset-y-0 lg:right-0 lg:w-1/2 lg:h-full">
          <Image media={props.fields.image} />
        </div>
      </main>
    </div>
  );
};

export default withDatasourceCheck()<HeroProps>(Hero);
Scaffold23.png

The screen has changed dramatically. Now let's reflect this code in the GitHub repository. After a while, the build in Vercel is completed and you can now edit the page in the Experience Editor as shown below.

Scaffold24.png

Summary

In creating the component, I ran the command jss scaffold, which resulted in two files. The role of each file is

  • sitecore/definitions/components/Hero.sitecore.ts Define data to be managed by Sitecore
  • src/components/Hero.tsx Rendering to display the page

In Sitecore, we created the item, displayed the data, and used the Tailwind CSS template to display the data in a reasonable way. The data is displayed on the screen using the Tailwind CSS template.

Tags