Skip to content

Commit

Permalink
feat(translations): handle internationalized string in GROQ queries
Browse files Browse the repository at this point in the history
  • Loading branch information
mathiazom committed Oct 8, 2024
1 parent 1c86f59 commit 51a3a40
Show file tree
Hide file tree
Showing 38 changed files with 316 additions and 160 deletions.
14 changes: 9 additions & 5 deletions src/app/(main)/[lang]/[slug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ import { BlogPage, PageBuilder, Post } from "studio/lib/interfaces/pages";
import { CustomerCasePage } from "studio/lib/interfaces/specialPages";
import {
COMPANY_LOCATIONS_QUERY,
LEGAL_DOCUMENTS_BY_SLUG_AND_LANG_QUERY,
LEGAL_DOCUMENT_BY_SLUG_AND_LANG_QUERY,
} from "studio/lib/queries/admin";
import {
BLOG_PAGE_QUERY,
PAGE_BY_SLUG_QUERY,
POSTS_QUERY,
SEO_SLUG_QUERY,
SLUG_QUERY,
} from "studio/lib/queries/pages";
import {
COMPENSATIONS_PAGE_QUERY,
Expand Down Expand Up @@ -67,11 +67,15 @@ async function Page({ params }: Props) {
initialCustomerCases,
initialLegalDocument,
] = await Promise.all([
loadStudioQuery<PageBuilder>(SLUG_QUERY, { slug }, { perspective }),
loadStudioQuery<PageBuilder>(
PAGE_BY_SLUG_QUERY,
{ slug, language: lang },
{ perspective },
),
loadStudioQuery<BlogPage>(BLOG_PAGE_QUERY, { slug }, { perspective }),
loadStudioQuery<CompensationsPage>(
COMPENSATIONS_PAGE_QUERY,
{ slug },
{ slug, language: lang },
{ perspective },
),
loadStudioQuery<CompanyLocation[]>(
Expand All @@ -85,7 +89,7 @@ async function Page({ params }: Props) {
{ perspective },
),
loadStudioQuery<LegalDocument>(
LEGAL_DOCUMENTS_BY_SLUG_AND_LANG_QUERY,
LEGAL_DOCUMENT_BY_SLUG_AND_LANG_QUERY,
{ slug, language: lang },
{ perspective },
),
Expand Down
6 changes: 5 additions & 1 deletion src/app/(main)/[lang]/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,11 @@ export default async function Layout({
initialLegal,
initialBrandAssets,
] = await Promise.all([
loadStudioQuery<Navigation>(NAV_QUERY, {}, { perspective }),
loadStudioQuery<Navigation>(
NAV_QUERY,
{ language: params.lang },
{ perspective },
),
loadStudioQuery<CompanyInfo>(COMPANY_INFO_QUERY, {}, { perspective }),
loadStudioQuery<SocialMediaProfiles | null>(
SOME_PROFILES_QUERY,
Expand Down
6 changes: 3 additions & 3 deletions src/app/(main)/[lang]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { client } from "studio/lib/client";
import { LinkType } from "studio/lib/interfaces/navigation";
import { PageBuilder } from "studio/lib/interfaces/pages";
import { LanguageObject } from "studio/lib/interfaces/supportedLanguages";
import { PAGE_QUERY, SEO_PAGE_QUERY } from "studio/lib/queries/pages";
import { PAGE_QUERY, PAGE_SEO_QUERY } from "studio/lib/queries/pages";
import {
LANDING_PAGE_REF_QUERY,
LANGUAGES_QUERY,
Expand All @@ -21,7 +21,7 @@ export async function generateMetadata(): Promise<Metadata> {
const { data: landingId } = await loadStudioQuery<string>(
LANDING_PAGE_REF_QUERY,
);
const seo = await fetchSeoData(SEO_PAGE_QUERY, { id: landingId });
const seo = await fetchSeoData(PAGE_SEO_QUERY, { id: landingId });
return generateMetadataFromSeo(seo);
}

Expand Down Expand Up @@ -84,7 +84,7 @@ const Home = async ({ params }: Props) => {

const initialLandingPage = await loadStudioQuery<PageBuilder>(
PAGE_QUERY,
{ id: landingId },
{ id: landingId, language: params.lang },
{ perspective },
);

Expand Down
4 changes: 2 additions & 2 deletions src/app/(main)/legal/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import Legal from "src/blog/components/legal/Legal";
import LegalPreview from "src/blog/components/legal/LegalPreview";
import { getDraftModeInfo } from "src/utils/draftmode";
import { LegalDocument } from "studio/lib/interfaces/legalDocuments";
import { LEGAL_DOCUMENTS_BY_SLUG_AND_LANG_QUERY } from "studio/lib/queries/admin";
import { LEGAL_DOCUMENT_BY_SLUG_AND_LANG_QUERY } from "studio/lib/queries/admin";
import { loadStudioQuery } from "studio/lib/store";

export const dynamic = "force-dynamic";
Expand All @@ -20,7 +20,7 @@ async function Page({ params }: Props) {
const { perspective, isDraftMode } = getDraftModeInfo();

const initialDocument = await loadStudioQuery<LegalDocument>(
LEGAL_DOCUMENTS_BY_SLUG_AND_LANG_QUERY,
LEGAL_DOCUMENT_BY_SLUG_AND_LANG_QUERY,
{ slug: id, language: "en" }, //TODO: replace this with selected language for the page
{ perspective },
);
Expand Down
9 changes: 6 additions & 3 deletions src/blog/components/legal/LegalPreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import { QueryResponseInitial, useQuery } from "@sanity/react-loader";

import { LegalDocument } from "studio/lib/interfaces/legalDocuments";
import { NAV_QUERY } from "studio/lib/queries/siteSettings";
import { LEGAL_DOCUMENT_BY_SLUG_AND_LANG_QUERY } from "studio/lib/queries/admin";

import Legal from "./Legal";

Expand All @@ -12,8 +12,11 @@ export default function LegalPreview({
initialDocument: QueryResponseInitial<LegalDocument>;
}) {
const { data: newDoc } = useQuery<LegalDocument | null>(
NAV_QUERY,
{},
LEGAL_DOCUMENT_BY_SLUG_AND_LANG_QUERY,
{
slug: initialDocument.data.slug,
language: initialDocument.data.language,
},
{ initial: initialDocument },
);

Expand Down
5 changes: 4 additions & 1 deletion src/compensations/CompensationsPreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ const CompensationsPreview = ({
}: CompensationsPreviewProps) => {
const { data: compensationsData } = useQuery<CompensationsPage>(
COMPENSATIONS_PAGE_QUERY,
{ slug: initialCompensations.data.slug.current },
{
slug: initialCompensations.data.slug,
language: initialCompensations.data.language,
},
{ initial: initialCompensations },
);

Expand Down
39 changes: 19 additions & 20 deletions src/components/link/CustomLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,6 @@ interface ICustomLink {
}

const CustomLink = ({ type = "link", link, isSelected }: ICustomLink) => {
const linkTitle = link.linkTitle;
// TODO: pick title based on selected language
const linkTitleValue =
(typeof linkTitle === "string" ? linkTitle : linkTitle[0].value) ?? "";
const href = getHref(link);
const newTab = link.newTab;
const target = newTab ? "_blank" : undefined;
Expand All @@ -28,29 +24,32 @@ const CustomLink = ({ type = "link", link, isSelected }: ICustomLink) => {
? `${styles.headerLink} ${isSelected ? styles.selected : ""}`
: styles.footerLink;

return type === "link" ? (
<div className={styles.wrapper}>
return (
link.linkTitle &&
(type === "link" ? (
<div className={styles.wrapper}>
<Link
className={styles.link}
href={href}
target={target}
rel={rel}
aria-label={link.ariaLabel}
>
<span className={styles.span}>{link.linkTitle}</span>
</Link>
<div className={styles.underline}></div>
</div>
) : (
<Link
className={styles.link}
className={className}
href={href}
target={target}
rel={rel}
aria-label={link.ariaLabel}
>
<span className={styles.span}>{linkTitleValue}</span>
{link.linkTitle}
</Link>
<div className={styles.underline}></div>
</div>
) : (
<Link
className={className}
href={href}
target={target}
rel={rel}
aria-label={link.ariaLabel}
>
{linkTitleValue}
</Link>
))
);
};

Expand Down
5 changes: 1 addition & 4 deletions src/components/linkButton/LinkButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,7 @@ const typeClassMap: { [key in LinkButtonType]: string } = {
const LinkButton = ({ isSmall, type = "primary", link }: IButton) => {
const className = `${styles.button} ${isSmall ? styles.small : ""} ${typeClassMap[type]}`;
const href = getHref(link);
const linkTitle = link.linkTitle;
// TODO: pick title based on selected language
const linkTitleValue =
typeof linkTitle === "string" ? linkTitle : linkTitle[0].value;
const linkTitleValue = link.linkTitle;
return (
href &&
linkTitleValue && (
Expand Down
6 changes: 5 additions & 1 deletion src/components/navigation/footer/FooterPreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,11 @@ export default function FooterPreview({
initialLegal: QueryResponseInitial<LegalDocument[] | null>;
language: string;
}) {
const newNav = useInitialData(NAV_QUERY, initialNav);
const { data: newNav } = useQuery(
NAV_QUERY,
{ language },
{ initial: initialNav },
);
const newCompanyInfo = useInitialData(COMPANY_INFO_QUERY, initialCompanyInfo);
const newBrandAssets = useInitialData(BRAND_ASSETS_QUERY, initialBrandAssets);
const newSoMedata = useInitialData(SOME_PROFILES_QUERY, initialSoMe);
Expand Down
2 changes: 1 addition & 1 deletion src/components/navigation/header/HeaderPreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export default function HeaderPreview({
}) {
const { data: newNav } = useQuery<Navigation | null>(
NAV_QUERY,
{},
{ language: initialNav.data.language },
{ initial: initialNav },
);
const { data: newBrandAssets } = useQuery<BrandAssets | null>(
Expand Down
2 changes: 2 additions & 0 deletions src/components/navigation/mockData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { linkID } from "studio/schemas/objects/link";
// Mock Navigation Data
export const mockNavigation: Navigation = {
_id: "main-navigation",
language: "en",
main: [
{
_key: "functionality",
Expand Down Expand Up @@ -63,6 +64,7 @@ export const mockNavigation: Navigation = {
sectionTitle: "Social Media",
sectionType: SectionType.SocialMedia,
socialMediaLinks: {
_type: "reference",
_ref: "soMeLinksID",
},
},
Expand Down
2 changes: 1 addition & 1 deletion src/components/sections/article/ArticlePreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export default function ArticlePreview({
}: PreviewProps) {
const { data } = useQuery<PageBuilder>(
PAGE_QUERY,
{ id: initialData.data._id },
{ id: initialData.data._id, language: initialData.data.language },
{ initial: initialData },
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export default function CallToActionPreview({
}: PreviewProps) {
const { data: newData } = useQuery<PageBuilder | null>(
PAGE_QUERY,
{ id: initialData.data._id },
{ id: initialData.data._id, language: initialData.data.language },
{ initial: initialData },
);

Expand Down
2 changes: 1 addition & 1 deletion src/components/sections/callout/CalloutPreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export default function CalloutPreview({
}: PreviewProps) {
const { data: newData } = useQuery<PageBuilder | null>(
PAGE_QUERY,
{ id: initialData.data._id },
{ id: initialData.data._id, language: initialData.data.language },
{ initial: initialData },
);

Expand Down
2 changes: 1 addition & 1 deletion src/components/sections/grid/GridPreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export default function GridPreview({
}: PreviewProps) {
const { data: newData } = useQuery<PageBuilder | null>(
PAGE_QUERY,
{ id: initialData.data._id },
{ id: initialData.data._id, language: initialData.data.language },
{ initial: initialData },
);

Expand Down
2 changes: 1 addition & 1 deletion src/components/sections/hero/HeroPreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export default function HeroPreview({
}: HeroPreviewProps) {
const { data: newData } = useQuery<PageBuilder | null>(
PAGE_QUERY,
{ id: initialData.data._id },
{ id: initialData.data._id, language: initialData.data.language },
{ initial: initialData },
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export default function ImageSectionComponentPreview({
}: PreviewProps) {
const { data: newData } = useQuery<PageBuilder | null>(
PAGE_QUERY,
{ id: initialData.data._id },
{ id: initialData.data._id, language: initialData.data.language },
{ initial: initialData },
);

Expand Down
2 changes: 1 addition & 1 deletion src/components/sections/logoSalad/LogoSaladPreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export default function LogoSaladPreview({
}: PreviewProps) {
const { data: newData } = useQuery<PageBuilder | null>(
PAGE_QUERY,
{ id: initialData.data._id },
{ id: initialData.data._id, language: initialData.data.language },
{ initial: initialData },
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export default function TestimonialsPreview({
}: PreviewProps) {
const { data: newData } = useQuery<PageBuilder | null>(
PAGE_QUERY,
{ id: initialData.data._id },
{ id: initialData.data._id, language: initialData.data.language },
{ initial: initialData },
);

Expand Down
23 changes: 18 additions & 5 deletions src/middlewares/languageMiddleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import {
LANGUAGES_QUERY,
} from "studio/lib/queries/siteSettings";
import {
SLUG_FIELD_TRANSLATIONS_FROM_LANGUAGE_QUERY,
SLUG_FIELD_TRANSLATIONS_TO_LANGUAGE_QUERY,
SLUG_TRANSLATIONS_FROM_LANGUAGE_QUERY,
SLUG_TRANSLATIONS_TO_LANGUAGE_QUERY,
} from "studio/lib/queries/slugTranslations";
Expand All @@ -22,15 +24,26 @@ async function translateSlug(
if (slug.length === 0) {
return slug;
}
const slugTranslations = await client.fetch<SlugTranslations | null>(
const queryParams = {
slug,
language: sourceLanguageId ?? targetLanguageId,
};
// query document-based slug translations
let slugTranslations = await client.fetch<SlugTranslations | null>(
sourceLanguageId !== undefined
? SLUG_TRANSLATIONS_FROM_LANGUAGE_QUERY
: SLUG_TRANSLATIONS_TO_LANGUAGE_QUERY,
{
slug,
language: sourceLanguageId ?? targetLanguageId,
},
queryParams,
);
if (slugTranslations === null) {
// try field-based slug translations instead
slugTranslations = await client.fetch<SlugTranslations | null>(
sourceLanguageId !== undefined
? SLUG_FIELD_TRANSLATIONS_FROM_LANGUAGE_QUERY
: SLUG_FIELD_TRANSLATIONS_TO_LANGUAGE_QUERY,
queryParams,
);
}
return slugTranslations?._translations.find(
(translation) =>
translation !== null && translation.language === targetLanguageId,
Expand Down
19 changes: 17 additions & 2 deletions src/utils/hooks/useLanguage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ import { fetchWithToken } from "studio/lib/fetchWithToken";
import { SlugTranslations } from "studio/lib/interfaces/slugTranslations";
import { LanguageObject } from "studio/lib/interfaces/supportedLanguages";
import { LANGUAGES_QUERY } from "studio/lib/queries/siteSettings";
import { SLUG_TRANSLATIONS_FROM_LANGUAGE_QUERY } from "studio/lib/queries/slugTranslations";
import {
SLUG_FIELD_TRANSLATIONS_FROM_LANGUAGE_QUERY,
SLUG_TRANSLATIONS_FROM_LANGUAGE_QUERY,
} from "studio/lib/queries/slugTranslations";

/**
* Client hook providing access to the available Sanity translations for the given slug
Expand Down Expand Up @@ -34,7 +37,19 @@ function useSlugTranslations(
slug,
language: currentLanguage?.id,
},
).then(setSlugTranslationsData);
).then(async (translations) => {
if (translations !== null) {
setSlugTranslationsData(translations);
}
const fieldTranslations = await fetchWithToken<SlugTranslations | null>(
SLUG_FIELD_TRANSLATIONS_FROM_LANGUAGE_QUERY,
{
slug,
language: currentLanguage?.id,
},
);
setSlugTranslationsData(fieldTranslations);
});
}, [currentLanguage, slug]);

const slugTranslations =
Expand Down
Loading

0 comments on commit 51a3a40

Please sign in to comment.