Skip to content

Conversation

@colton-demetriou
Copy link
Contributor

@colton-demetriou colton-demetriou commented Jan 6, 2026

Tested manually in platform, verified that the new fields are respected when generating page urls for locations, directory entities, and locators. Also verifed that view live site works correctly when fetching page generations, and goes to incorrect url without storm changes when constructing the url. Lastly, tested with storm changes and verified that it goes to the correct url.

Test site: https://dev.yext.com/s/1000163760/yextsites/66490/branch/6132/deploys/recent
Test site (DM city): https://dev.yext.com/s/1000163760/yextsites/66492/pagesets

@colton-demetriou colton-demetriou added the create-dev-release Triggers dev release workflow label Jan 6, 2026
@pkg-pr-new
Copy link

pkg-pr-new bot commented Jan 6, 2026

commit: eda2263

@colton-demetriou colton-demetriou marked this pull request as ready for review January 6, 2026 21:14
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 6, 2026

Walkthrough

This PR makes pageset-level locale configuration (primaryLocale and includeLocalePrefixForPrimaryLocale) influential across URL/path resolution. It parses _pageset (string or object) and computes a localePrefix that is conditionally applied to slugs, address-based paths, and id-based paths. Changes touch resolvePageSetUrlTemplate/resolveUrlTemplate/buildUrlFromTemplate/getLocationPath and mergeMeta to derive primary locale behavior from pageset config instead of assuming "en". Template code (locator) delegates path resolution to the shared resolver and getPath now accepts relativePrefixToRoot.

Sequence Diagram(s)

sequenceDiagram
    participant Template as Template (locator/directory)
    participant Resolver as resolvePageSetUrlTemplate
    participant ResolverCore as resolveUrlTemplate / buildUrlFromTemplate
    participant Location as getLocationPath
    participant Pageset as _pageset (config)

    Template->>Resolver: document, relativePrefixToRoot
    Resolver->>Pageset: read/parse _pageset
    Resolver->>ResolverCore: pagesetConfig, document, relativePrefixToRoot
    ResolverCore->>ResolverCore: derive primaryLocale, compute localePrefix
    ResolverCore->>Location: request path for location parts (slug/address/id)
    Location->>ResolverCore: return path segments (with localePrefix applied)
    ResolverCore->>Resolver: assemble final URL
    Resolver-->>Template: resolved path
Loading

Possibly related PRs

Suggested reviewers

  • benlife5
  • asanehisa
🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately reflects the main change: updating link generation to respect primary locale and include locale prefix settings.
Description check ✅ Passed The description is related to the changeset and provides testing context, though it focuses more on manual validation than technical details.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
packages/visual-editor/src/utils/mergeMeta.ts (1)

11-16: LGTM! Consider extracting the pageset parsing logic.

The parsing logic correctly handles both string and object forms of _pageset with appropriate fallbacks. This same parsing pattern appears in resolveUrlTemplate.ts (lines 34-38 and 70-73). Consider extracting this into a shared utility function to avoid duplication.

📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e82dc4a and 4277f8f.

📒 Files selected for processing (7)
  • packages/visual-editor/src/utils/getLocationPath.test.ts
  • packages/visual-editor/src/utils/getLocationPath.ts
  • packages/visual-editor/src/utils/mergeMeta.ts
  • packages/visual-editor/src/utils/resolveUrlTemplate.test.ts
  • packages/visual-editor/src/utils/resolveUrlTemplate.ts
  • packages/visual-editor/src/vite-plugin/templates/directory.tsx
  • packages/visual-editor/src/vite-plugin/templates/locator.tsx
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-11-06T14:55:12.395Z
Learnt from: benlife5
Repo: yext/visual-editor PR: 862
File: packages/visual-editor/src/utils/schema/resolveSchema.ts:118-135
Timestamp: 2025-11-06T14:55:12.395Z
Learning: In `packages/visual-editor/src/utils/schema/resolveSchema.ts`, the `OpeningHoursSchema` and `PhotoGallerySchema` functions from `yext/pages-components` contain internal type validation and handle invalid inputs gracefully (returning empty objects or undefined) rather than throwing TypeErrors, so no pre-validation guards are needed before calling them.

Applied to files:

  • packages/visual-editor/src/vite-plugin/templates/directory.tsx
  • packages/visual-editor/src/vite-plugin/templates/locator.tsx
🧬 Code graph analysis (5)
packages/visual-editor/src/utils/getLocationPath.test.ts (1)
packages/visual-editor/src/utils/getLocationPath.ts (1)
  • getLocationPath (11-72)
packages/visual-editor/src/utils/resolveUrlTemplate.test.ts (2)
packages/visual-editor/src/utils/resolveUrlTemplate.ts (1)
  • resolvePageSetUrlTemplate (61-84)
packages/visual-editor/src/utils/index.ts (1)
  • resolvePageSetUrlTemplate (23-23)
packages/visual-editor/src/vite-plugin/templates/directory.tsx (4)
packages/visual-editor/src/vite-plugin/templates/locator.tsx (1)
  • getPath (96-101)
packages/visual-editor/src/vite-plugin/templates/main.tsx (1)
  • getPath (98-103)
packages/visual-editor/src/utils/resolveUrlTemplate.ts (1)
  • resolvePageSetUrlTemplate (61-84)
packages/visual-editor/src/utils/index.ts (1)
  • resolvePageSetUrlTemplate (23-23)
packages/visual-editor/src/utils/resolveUrlTemplate.ts (2)
packages/visual-editor/src/utils/index.ts (1)
  • StreamDocument (8-8)
packages/visual-editor/src/utils/applyTheme.ts (1)
  • StreamDocument (20-39)
packages/visual-editor/src/vite-plugin/templates/locator.tsx (3)
packages/visual-editor/src/vite-plugin/templates/directory.tsx (1)
  • getPath (95-100)
packages/visual-editor/src/vite-plugin/templates/main.tsx (1)
  • getPath (98-103)
packages/visual-editor/src/utils/resolveUrlTemplate.ts (1)
  • resolvePageSetUrlTemplate (61-84)
🔇 Additional comments (20)
packages/visual-editor/src/utils/mergeMeta.ts (1)

18-25: LGTM!

The isPrimaryLocale derivation now correctly uses the configurable primaryLocale from pageset config, with proper backward compatibility defaulting to "en".

packages/visual-editor/src/vite-plugin/templates/locator.tsx (2)

27-28: LGTM!

The import of resolvePageSetUrlTemplate correctly replaces the previous normalizeSlug import, aligning with the centralized URL template resolution approach.


96-101: LGTM!

The getPath implementation is consistent with directory.tsx and main.tsx templates, delegating path resolution to resolvePageSetUrlTemplate for unified locale-aware URL construction.

packages/visual-editor/src/utils/getLocationPath.test.ts (4)

119-154: LGTM! Good coverage of pagesetConfig scenarios.

The tests comprehensively cover the new includeLocalePrefixForPrimaryLocale behavior and the special handling for directory entities (slug without address).


156-200: LGTM!

Good coverage of custom primaryLocale configurations with proper verification of locale prefix behavior for both primary and non-primary locales.


202-295: LGTM!

Tests correctly verify the includeLocalePrefixForPrimaryLocale flag behavior for both true and false (default) values across different path types (address-based and ID-based).


297-371: LGTM!

Good coverage of combined configurations (custom primary locale with prefix flag) and backward compatibility when pagesetConfig is not provided.

packages/visual-editor/src/utils/resolveUrlTemplate.test.ts (3)

310-312: LGTM!

The updated expectation correctly reflects the new behavior: non-primary locales using the primary template should now receive a locale prefix.


351-354: LGTM!

Good documentation in the comments explaining the default behavior when isPrimaryLocale is missing.


461-625: LGTM! Comprehensive test coverage for new configuration options.

The tests thoroughly cover:

  • Custom primaryLocale from pageset config
  • includeLocalePrefixForPrimaryLocale flag (true/false)
  • Double-prefix prevention when template already includes [[locale]]
  • Combinations with relativePrefixToRoot
  • Backward compatibility when config fields are missing
packages/visual-editor/src/utils/getLocationPath.ts (4)

11-18: LGTM!

Good API design with optional pagesetConfig parameter maintaining backward compatibility.


28-38: LGTM!

The locale prefix logic correctly implements the configurable behavior with appropriate defaults for backward compatibility.


62-65: LGTM!

For location entities (slug with address), the locale prefix is correctly applied based on the computed localePath.


40-60: Verify non-primary locale handling for directory entities.

The special handling for directory entities (slug without address) only adds locale prefix when isPrimaryLocale && includeLocalePrefixForPrimaryLocale. For non-primary locales, the slug is returned directly (line 59).

This is intentional—directory entity slugs for non-primary locales already include the locale prefix in the slug itself. The test at lines 140-151 of getLocationPath.test.ts confirms this: a non-primary locale with slug "es/locator-page" is returned as-is. Multiple other test files (Breadcrumbs.test.tsx, Directory.test.tsx) also show directory parent slugs with locale prefixes (e.g., "en/index.html").

packages/visual-editor/src/utils/resolveUrlTemplate.ts (4)

33-46: LGTM!

The pageset config extraction is correctly added to resolveUrlTemplateOfChild to propagate locale configuration to the core resolver.


70-83: LGTM!

Consistent implementation with resolveUrlTemplateOfChild for pageset config extraction.


90-130: LGTM!

The core resolver correctly propagates pagesetConfig to both getLocationPath and buildUrlFromTemplate for consistent locale-aware URL construction.


165-195: Note potential divergence in isPrimaryLocale determination.

Template selection (line 139) uses streamDocument.__?.isPrimaryLocale !== false, while buildUrlFromTemplate (line 184) recomputes isPrimaryLocale as locale === primaryLocale.

In edge cases where __?.isPrimaryLocale is explicitly true but locale !== primaryLocale, the primary template will be selected but a locale prefix will still be added. This defensive behavior seems intentional for data consistency but worth documenting.

packages/visual-editor/src/vite-plugin/templates/directory.tsx (2)

27-28: LGTM!

Import updated correctly to use the new resolvePageSetUrlTemplate function.


95-100: LGTM!

The getPath implementation is consistent with locator.tsx and main.tsx, providing unified locale-aware URL construction across all template types.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In @packages/visual-editor/src/utils/resolveUrlTemplate.test.ts:
- Around line 553-574: The test "does not double-prefix when alternate template
already includes [[locale]]" is inconsistent: docWithAlternateTemplate includes
an alternate template with [[locale]] so resolvePageSetUrlTemplate should
produce a single locale prefix; update the test to expect
"es/ny/new-york/61-9th-ave" (remove the double "es/") and adjust the test
comment to reflect that the alternate template already provides the locale
prefix and no additional prefix should be added; reference
resolvePageSetUrlTemplate and the docWithAlternateTemplate fixture when making
the change.
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4277f8f and a6547da.

📒 Files selected for processing (6)
  • packages/visual-editor/src/utils/getLocationPath.test.ts
  • packages/visual-editor/src/utils/getLocationPath.ts
  • packages/visual-editor/src/utils/resolveUrlTemplate.test.ts
  • packages/visual-editor/src/utils/resolveUrlTemplate.ts
  • packages/visual-editor/src/utils/schema/resolveSchema.ts
  • packages/visual-editor/src/vite-plugin/templates/directory.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/visual-editor/src/utils/resolveUrlTemplate.ts
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-11-06T14:55:12.395Z
Learnt from: benlife5
Repo: yext/visual-editor PR: 862
File: packages/visual-editor/src/utils/schema/resolveSchema.ts:118-135
Timestamp: 2025-11-06T14:55:12.395Z
Learning: In `packages/visual-editor/src/utils/schema/resolveSchema.ts`, the `OpeningHoursSchema` and `PhotoGallerySchema` functions from `yext/pages-components` contain internal type validation and handle invalid inputs gracefully (returning empty objects or undefined) rather than throwing TypeErrors, so no pre-validation guards are needed before calling them.

Applied to files:

  • packages/visual-editor/src/utils/schema/resolveSchema.ts
  • packages/visual-editor/src/vite-plugin/templates/directory.tsx
📚 Learning: 2025-12-12T19:26:15.855Z
Learnt from: benlife5
Repo: yext/visual-editor PR: 942
File: packages/visual-editor/src/utils/schema/schemaBlocks.ts:29-35
Timestamp: 2025-12-12T19:26:15.855Z
Learning: In packages/visual-editor/src/utils/schema/schemaBlocks.ts, when siteDomain is missing (non-live/preview environments), schema id fields should use relative URLs rather than bare fragments, since Google will only crawl production sites where siteDomain is populated.

Applied to files:

  • packages/visual-editor/src/utils/schema/resolveSchema.ts
🧬 Code graph analysis (3)
packages/visual-editor/src/utils/schema/resolveSchema.ts (1)
packages/visual-editor/src/utils/resolveUrlTemplate.ts (2)
  • resolveUrlTemplateOfChild (20-39)
  • resolvePageSetUrlTemplate (53-74)
packages/visual-editor/src/utils/resolveUrlTemplate.test.ts (2)
packages/visual-editor/src/utils/resolveUrlTemplate.ts (1)
  • resolvePageSetUrlTemplate (53-74)
packages/visual-editor/src/utils/index.ts (1)
  • resolvePageSetUrlTemplate (23-23)
packages/visual-editor/src/utils/getLocationPath.test.ts (1)
packages/visual-editor/src/utils/getLocationPath.ts (1)
  • getLocationPath (11-50)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: call_unit_test / unit_tests (24.x)
  • GitHub Check: call_unit_test / unit_tests (22.x)
  • GitHub Check: call_unit_test / unit_tests (20.x)
  • GitHub Check: semgrep/ci
  • GitHub Check: create-dev-release
🔇 Additional comments (7)
packages/visual-editor/src/vite-plugin/templates/directory.tsx (2)

27-27: LGTM!

Import reordering is purely cosmetic with no functional impact.


95-104: Consider aligning getPath with the new primary locale logic.

The getPath function uses a hardcoded "en" check (document.locale !== "en") for determining locale prefixes, while other files in this PR now derive the primary locale from pageset configuration. This could lead to inconsistent URL generation if the primary locale is not English.

If this is intentional for directory templates (e.g., directory pages follow different rules), this is fine. Otherwise, consider updating this to use the pageset config pattern introduced elsewhere.

packages/visual-editor/src/utils/schema/resolveSchema.ts (1)

226-256: LGTM! Well-structured branching for directory vs. location entities.

The logic correctly differentiates between directory entities (using slugs directly) and location entities (using URL templates with locale prefix logic). The comment at lines 240-242 clearly explains the intentional difference in behavior.

packages/visual-editor/src/utils/resolveUrlTemplate.test.ts (1)

461-626: Good coverage for new primary locale configuration options.

The new test block thoroughly covers the various combinations of primaryLocale and includeLocalePrefixForPrimaryLocale settings, including backward compatibility and interaction with relativePrefixToRoot.

packages/visual-editor/src/utils/getLocationPath.test.ts (1)

119-393: Comprehensive test coverage for pageset config locale handling.

The tests thoroughly cover all combinations of primaryLocale and includeLocalePrefixForPrimaryLocale, including edge cases like double prefixes and backward compatibility when pagesetConfig is missing.

packages/visual-editor/src/utils/getLocationPath.ts (2)

24-38: LGTM! Clean implementation of locale prefix logic.

The pageset config parsing correctly handles both string and object forms of _pageset, with proper fallbacks to empty objects. The localePrefix computation clearly expresses the intent: prefix is applied when not primary locale OR when includeLocalePrefixForPrimaryLocale is enabled.


40-49: Verify intentional difference in slug normalization.

Slug paths (line 42) are returned directly without normalizeSlug, while address/id paths (line 49) go through normalization. This is likely intentional since slugs are expected to be pre-normalized, but worth confirming this assumption holds for all callers.

github-actions bot and others added 9 commits January 8, 2026 18:27
[Mocks](https://www.figma.com/design/sX3bkzkEpQ3g2mJrfSSdmd/Quickstart-Template--2025-?node-id=17998-380910&m=dev)

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Used capsizecss to generate fallback font transformations for each
Google font. This significantly reduces layout shift when the fallback
font is replaced with the downloaded font. There is script in the
library to generate these font face declarations so that the full
capcize package does not need to be installed in the starter.


https://smartly-brilliant-gerbil.dev.pgsdemo.com/ny/new-york/99-9th-avenue


https://github.com/user-attachments/assets/a8388074-7885-4fea-9a17-f5e5c8591828

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Uses refReviews_agg from the document rather than a content endpoint.
Allows reviews to be SSR'ed

The stream does not currently support review responses but we are ok
with dropping that for now. Ideally, it should automatically work if
Dragonbone adds it in the same format that is used in the content
endpoint

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
…967)

Tickets - [OPAQF-41](https://yext.atlassian.net/browse/OPAQF-41),
[OPAQF-53](https://yext.atlassian.net/browse/OPAQF-53). Closed [previous
PR](#962).

- Added new prop for TranslatableCTA - openInNewTab.
- Added openInNewTab option for links in the Expanded Header and
Expanded Footer.
- Added a prop to center-align the Secondary Footer section.
- Added relevant test cases.
- Used inline instead of flex for the external-link indicator to prevent
forced center alignment on mobile.
- Did fixes on older PR.

Ran test on older header by mistake, please ignore.

https://github.com/user-attachments/assets/3da9a082-5e4f-49b4-a345-997c4f1279b6

---------

Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Tickets - [OPAQF-19,](https://yext.atlassian.net/browse/OPAQF-19),
[OPAQF-84](https://yext.atlassian.net/browse/OPAQF-84).

- Renamed Media orientation to Media Position in promo section.
- Added default truncate field.

Didn't run any test cases as there may not be any noticeable visual
difference.

https://github.com/user-attachments/assets/261881e0-5717-4576-8548-abeef9395a4c

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
Tickets - [OPAQF-49](https://yext.atlassian.net/browse/OPAQF-49),
[OPAQF-59](https://yext.atlassian.net/browse/OPAQF-59)

- Reduced Event Section's description to 2 lines.
- Updated body and heading to use proportional line-heights (1.5 for
body text, 1.2 for headings) instead of calculated pixel-based values.

https://github.com/user-attachments/assets/c4cce286-9b5d-4bbd-9328-1dde7ddbcf48

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
asanehisa
asanehisa previously approved these changes Jan 8, 2026
Copy link
Contributor

@asanehisa asanehisa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just confirming we do want the locale in the path even if the locale already exists in it?

Copy link
Collaborator

@mkilpatrick mkilpatrick left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This lgtm now but I want others to really dive into it. I still think there's some refactoring we can do so we're not making the same checks in 3 different places. Someone can take it over next week.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

create-dev-release Triggers dev release workflow

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants