Locale data
Static site data for each locale is grouped into two general categories: the "global" data and the "page" data. Global data refers to site-wide content—things like navigation menus, footers, and so on—while page data refers to page-specific content—things like a homepage header, or a biography for an "about" page.
All static locale data lives within the /src/locales/
directory, and is grouped into these two categories. You can treat the globals
directory as a reserved directory name, as all global (site-wide) data is compiled from within it. All other directories here, however, are page-level data directories which should match each page's filename as it exists in the /src/pages/
directory.
Within both /src/locales/globals/
and /src/locales/<page-name>/
, should live YAML files containing the actual locale data. Each YAML file's name should be the locale string as specified in the locale config, with a .yml
extension, except for the index.yml
file, which is a special case for each directory (more on that below).
Here is an example file tree, containing global data as well as data for two pages—all containing content for three locales:
.
└── src/
└── locales/
├── globals/
│ ├── en.yml
│ ├── es.yml
│ ├── fr.yml
│ └── index.yml
├── home/
│ ├── en.yml
│ ├── es.yml
│ ├── fr.yml
│ └── index.yml
└── features/
├── en.yml
├── es.yml
└── fr.yml
Locale data compilation
Under the hood, all of these files get compiled into two objects—globals
and page
—and are then passed to each page as props. This process is done via Next JS' getStaticProps
convention. The useLocale
hook is a convenient way to work with this data from any functional React component in your project.
globals
example
An example globals
YAML file for the "en"
locale:
meta:
title: My Cool Web App
description: The site-wide meta description.
og_alt: Description of the og image.
nav:
label: Main site navigation
items:
- id: home
label: Home
- id: features
label: Product Features
- id: contact
label: Get in touch
footer: © Company Name.
As mentioned, that data gets compiled into a page-level prop called globals
, for the current page and locale. Here's an example that uses that data (via useLocale
) from within an imaginary <Navigation />
component:
import { useLocale } from "@local/hooks"
const Navigation = () => {
const { globals } = useLocale()
return (
<nav aria-labelledby="nav-label">
<span id="nav-label" className="visually-hidden">{globals.nav.label}</span>
<ul>
{globals.nav.items.map(item => (
<li key={item.id}>{item.label}</li>
)}
</ul>
</nav>
)
}
export default Navigation
page
example
An example "Product Features" page YAML file for the "en"
locale:
meta:
title: Product Features
description: Our product is pretty cool. It does cool things.
features:
- id: 897213
image: path-to-some-image.jpg
image_alt: Description of image goes here.
description: Laborum sint ut mollit proident quis do proident ex laboris sint nisi.
- id: 216357
image: path-to-some-other-image.jpg
image_alt: Description of image goes here.
description: Consequat ea fugiat irure do magna fugiat ex minim aute proident ullamco.
- id: 187236
image: path-to-yet-another-image.jpg
image_alt: Description of image goes here.
description: Magna in laborum aliquip exercitation est est est.
This data gets compiled into a page-level prop called page
, for the current page and locale. Here's an example that uses that data (via useLocale
) from within an imaginary <FeatureList>
component:
import { useLocale } from "@local/hooks";
const FeatureList = ({}) => {
const { page } = useLocale();
return (
<ul>
{page.features.map((feature) => (
<li key={feature.id}>
<img src={feature.image} alt={featue.image_alt} />
<span>{feature.description}</span>
</li>
))}
</ul>
);
};
export default FeatureList;
index.yml
example
Each directory within /src/locales/
can contain an index.yml
. If inside global/
its data will be available as part of the globals
scope mentioned above, otherwise it will be part of the page
scope.
If inside a page locale directory, the data will be available for all locales, but those can still overwrite that data.
Let's say you have a list of downlodable PDFs that you want to display on the footer of your site. These PDFs are in english for all locales except for fr
. You can define the list in the index.yml
file and then overwrite it for the fr
locale instead of having to define it for each locale.
downloads:
- path-to-pdf-1.pdf
- path-to-pdf-2.pdf
- path-to-pdf-3.pdf
downloads:
- fr/path-to-pdf-1.pdf
- fr/path-to-pdf-2.pdf
- fr/path-to-pdf-3.pdf
The data is then merged and is available in the globals
scope.
import { useLocale } from "@local/hooks";
const Footer = ({}) => {
const { globals: { downloads } } = useLocale();
return (
<ul>
{downloads.map((path, i) => (
<li key={i}>
<a href={path} download><Icon id="download" /></a>
</li>
))}
</ul>
);
};
export default Footer;