Step 2: Global Data with a Site Entity

This guide accompanies the video walk-through and will provide you with code snippets and commands used in the video.

Using global data allows you to have a single source of truth for certain assets, like logos, photos, or taglines, which can be used on any page in your site. In this video, Aaron uses a site entity to power global data used across his blog. Specifically, he will:

  • Add a new stream to pull in the global data.
  • Use that global data to populate the home template, replacing the hard-coded values.
  • Use that global data in the blog post template to appear across all blog pages.
light bulb
Want to learn more?
If you want to see the finished code from the end of this section, clone the starter repo with git clone https://github.com/YextSolutions/pages-starter-react-blog and check out the global-data branch with git checkout global-data.

Walkthrough

1:15 Add a new file to your sites-config folder called site-stream.json.

1:28 Define your global site object with the following configuration:

{
  "$id": "site-entity",
  "filter": {
    "entityIds": ["site"]
  },
  "source": "knowledgeGraph",
  "fields": [
    "firstName",
    "lastName",
    "c_role",
    "c_headshot",
    "c_twitter",
    "c_github",
    "c_devTo",
    "c_introduction",
    "c_home",
    "c_interests",
    "c_skills"
  ],
  "localization": {
    "locales": ["en"]
  }
}

1:53 Replace the template code in src/templates/home.tsx with the following code that pulls info from the _site object and renders it:

const Home: Template<TemplateRenderProps> = ({
  document,
}: TemplateRenderProps) => {
  const { _site } = document;

  return (
    <HomeLayout
      GreetingContent={() => (
        <Greeting
          name={_site.firstName}
          role={_site.c_role}
          headshot={_site.headshot}
        />
      )}
      sections={[
        {
          title: "Home",
          Section: (
            <PersonalInfo
              twitter={_site.c_twitter}
              github={_site.c_github}
              devTo={_site.devTo}
              introduction={_site.c_introduction}
              home={_site.c_home}
              skills={_site.c_skills}
              interests={_site.c_interests}
            />
          ),
        },
        {
          title: "Blogs",
          Section: <></>,
        },
      ]}
    />
  );
};

2:38 In src/templates/blog-post.tsx, pull out the _site object from the document prop and update the template code to render the firstName, lastName, and c_headshot fields from the _site object.

const BlogPost: Template<TemplateRenderProps> = ({
  document,
}: TemplateProps) => {
  const { _site } = document;

  return (
    <>
      <div className="mx-auto flex w-full max-w-4xl flex-col items-start justify-center">
        <InfoSection titleCssStyles="text-5xl pb-4" title={document.name}>
          {document.c_coverPhoto && <Image image={document.c_coverPhoto} />}
          {/* new code starts here... */}
          <div className="flex items-center gap-2">
            {_site.c_headshot && (
              <Image
                className="rounded-full"
                image={_site.c_headshot}
                layout={"aspect"}
                aspectRatio={1}
                width={40}
              />
            )}
            <div className="flex gap-2 py-4">
              {(_site.firstName || _site.lastName) && (
                <p className="font-semibold">{`${_site.firstName} ${_site.lastName}`}</p>
              )}
              {(_site.firstName || _site.lastName) && document.datePosted && (
                <p className="font-semibold"></p>
              )}
              {document.datePosted && (
                <p className="font-semibold">
                  {formatDate(document.datePosted)}
                </p>
              )}
            </div>
          </div>
          {/* ...and ends here */}	
          <div className="font-display">{renderBlogContent(document.body)}</div>
        </InfoSection>
      </div>
    </>
  );
};

3:09 Run your site locally:

npm run dev

Access a few different blog posts from the local development landing page and confirm each now has a headshot and author name.