Conversation
|
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. |
af51870 to
5a3686e
Compare
ff87468 to
8d847df
Compare
## What's the purpose of this pull request? Add the fallback label to hCMS so it can be editable. We need it there so it can be translated through the CMS.⚠️ Breaking change: there is no more a hardcoded fallback label, the message necessarily has to come through CMS. This PR will be merged in the `feat/multilanguage` feature branch, which will be available only in the next faststore major version. ## How it works? It was hardcoded, so adding it to the hCMS schema allows it to be editable. ## How to test it? In a Search page, observe the breadcrumb, it should have the value configured through the hCMS. <img width="1028" height="501" alt="Screenshot 2025-11-04 at 10 27 49" src="https://github.com/user-attachments/assets/30d38c18-202c-4fa7-aeb5-5e8416019b4f" /> If the field is not being displayed in the hCMS, remember to cms sync and publish the page. <img width="1497" height="757" alt="Screenshot 2025-11-04 at 10 37 38" src="https://github.com/user-attachments/assets/d253597b-5953-4ebd-9931-2c3afb324994" /> ### Starters Deploy Preview - https://storeframework-cm652ufll028lmgv665a6xv0g-77wksgb4k.b.vtex.app/s?q=pizza ([PR](vtex-sites/faststoreqa.store#886)) ## References - [Jira task](https://vtex-dev.atlassian.net/browse/SFS-2921)
## What's the purpose of this pull request? Add the Sort by selector labels to hCMS so it can be editable. We need it there so it can be translated through the CMS.⚠️ Breaking change: there is no more sort options hardcoded, the values necessarily have to come through CMS. This PR will be merged in the `feat/multilanguage` feature branch, which will be available only in the next faststore major version. ## How it works? It was hardcoded, so adding it to the hCMS schema allows it to be editable. ## How to test it? In a Search page or PLP, observe the Sort by selector, it should have the values configured through the hCMS. | PLP | Search | | ---- | ---- | | <img width="1031" height="922" alt="Screenshot 2025-11-05 at 09 57 37" src="https://github.com/user-attachments/assets/40379935-78f7-402c-9020-662bdc824bbe" /> | <img width="1024" height="915" alt="Screenshot 2025-11-05 at 09 57 55" src="https://github.com/user-attachments/assets/bde4a107-b6dd-414e-a592-bb29ffae1788" /> | | <img width="1502" height="505" alt="Screenshot 2025-11-05 at 14 25 01" src="https://github.com/user-attachments/assets/f4c6fcbf-b4a1-4f8d-98ec-b49f7dfde6d5" /> | <img width="1502" height="438" alt="Screenshot 2025-11-05 at 14 25 18" src="https://github.com/user-attachments/assets/8f0f10aa-b38c-479e-9a09-3d58f9b582d8" /> | If the field is not being displayed in the hCMS, remember to cms sync and publish the page. ### Starters Deploy Preview - https://brandless-cma5xay4001f6dn4xjwato8b4-4tvja66oo.b.vtex.app/ ([PR](vtex-sites/brandless.store#113)) ## References - [Jira task](https://vtex-dev.atlassian.net/browse/SFS-2915)
Add the invalid quantity toast to hCMS so it can be editable. We need it there so it can be translated through the CMS.⚠️ Breaking change: there is no more a hardcoded message, it necessarily has to come through CMS. This PR will be merged in the `feat/multilanguage` feature branch, which will be available only in the next faststore major version. It was hardcoded, so adding it to the hCMS schema allows it to be editable. There are 3 places where it's being used: `SKUMatrixSidebar`, `SearchProductItem` and `ProductDetailsSettings`, those are related to 2 sections: `Navbar` and `ProductDetails`. So I've updated the schema of both sections. In the `brandless` account I've configured through hCMS those messages and I've enabled the quick order feature so we could test the change in the Navbar (this feature allows adding products directly to the cart through search terms). <img width="250" alt="Screenshot 2025-11-06 at 14 01 25" src="https://github.com/user-attachments/assets/a890c6d9-5fc7-4b45-b0c9-c0c47afe1f0e" /> | Navbar | PDP | | ---- | ---- | | <img width="1333" height="376" alt="Screenshot 2025-11-06 at 13 57 31" src="https://github.com/user-attachments/assets/0c07957a-8075-446f-9921-c112eaabb585" /> | <img width="1333" height="457" alt="Screenshot 2025-11-06 at 13 57 11" src="https://github.com/user-attachments/assets/750f7214-313d-4f46-a02c-a0d71b17d39c" /> | | <img width="1509" height="577" alt="Screenshot 2025-11-06 at 14 17 37" src="https://github.com/user-attachments/assets/f93be95e-a0a0-4119-9632-5dbd0e74a215" /> | <img width="1508" height="501" alt="Screenshot 2025-11-06 at 13 58 35" src="https://github.com/user-attachments/assets/af49ef79-c80f-491f-8ef9-78a32f30c436" /> | | The following SKU Matrix Sidebar is displayed after clicking in "select multiple" in the search suggestions: <img width="1505" height="585" alt="Screenshot 2025-11-06 at 15 20 38" src="https://github.com/user-attachments/assets/66afaae0-6615-4801-b296-5d5e68ab7cf1" /> | | - https://brandless-cma5xay4001f6dn4xjwato8b4-95qmbq4tq.b.vtex.app/ ([PR](vtex-sites/brandless.store#114)) - [Jira task](https://vtex-dev.atlassian.net/browse/SFS-2917)
## What's the purpose of this pull request? Make `ScrollToTopButton` text editable through hCMS by converting it from a hardcoded component to a CMS-managed section. **⚠️ Breaking Change**: The `ScrollToTopButton` has been removed from the PLP template and must now be manually added via hCMS to PLPs. Print PLP without ScrollToTopButton hardcoded and no setup in hCMS <img width="1800" height="1014" alt="image" src="https://github.com/user-attachments/assets/b547a62a-a2d1-4097-abb1-4b86a6e63f01" /> ## How it works? Removed hardcoded `ScrollToTopButton` from `ProductListing`. It is now rendered dynamically via hCMS with configurable text and icon position. CMS <img width="680" height="281" alt="Captura de Tela 2025-11-06 às 15 26 49" src="https://github.com/user-attachments/assets/9b64fe77-d207-4013-b5bf-a5a5305029da" /> <img width="1298" height="374" alt="Captura de Tela 2025-11-06 às 15 27 11" src="https://github.com/user-attachments/assets/20e74ee9-061a-4450-94e7-176b0c0e0425" /> <img width="1344" height="511" alt="Captura de Tela 2025-11-06 às 16 20 41" src="https://github.com/user-attachments/assets/1fc2ccdc-805d-4ee6-8aea-84616aefc159" /> ## How to test it? In a Search page or PLP, observe the Scroll to Top Button. It should have the text and icon position configured through the Headless CMS. ## References [Jira task](https://vtex-dev.atlassian.net/jira/software/c/projects/SFS/boards/1051?selectedIssue=SFS-2916)
## What's the purpose of this pull request? Add the product comparison sort options to hCMS so it can be editable. We need it there so it can be translated through the CMS.⚠️ Breaking change: there is no more hardcoded labels, it necessarily has to come through CMS. This PR will be merged in the `feat/multilanguage` feature branch, which will be available only in the next faststore major version. ## How it works? It was hardcoded, so adding it to the hCMS schema allows it to be editable. ## How to test it? Enable the product comparison feature in Search/PLP through hCMS and update the sort options labels: <img width="538" height="200" alt="Screenshot 2025-11-10 at 15 02 45" src="https://github.com/user-attachments/assets/c9f38ed2-6b9b-40b8-8061-107e8d9a712b" /> You can test the Search/PLP on desktop and mobile, choosing some products to compare and opening the product comparison sidebar. | Search | PLP | | ---- | ---- | | <img width="1001" height="472" alt="Screenshot 2025-11-10 at 15 10 18" src="https://github.com/user-attachments/assets/a4a61938-82cc-4cda-9f2e-2e24730ea77a" /> | <img width="996" height="467" alt="Screenshot 2025-11-10 at 15 09 11" src="https://github.com/user-attachments/assets/47937111-a2b0-41fe-b03b-1a9a51f6e0e8" /> | |<img width="1493" height="800" alt="Screenshot 2025-11-10 at 15 17 04" src="https://github.com/user-attachments/assets/f0686066-d333-4d4e-a497-5ebb80ccdf72" /> | <img width="1497" height="799" alt="Screenshot 2025-11-10 at 15 15 57" src="https://github.com/user-attachments/assets/cb6ac62a-7fe7-4f6d-a4b8-17111a1ac86a" /> | | <img width="316" height="682" alt="Screenshot 2025-11-10 at 15 17 20" src="https://github.com/user-attachments/assets/93ebae88-6ba4-4923-b96a-f7847f8408aa" /> | <img width="318" height="683" alt="Screenshot 2025-11-10 at 15 16 06" src="https://github.com/user-attachments/assets/14a31321-3bee-42a2-adc5-6dd33725612c" /> | ### Starters Deploy Preview - https://brandless-cma5xay4001f6dn4xjwato8b4-3wiqbhrja.b.vtex.app/ ([PR](vtex-sites/brandless.store#116)) ## References - [Jira task](https://vtex-dev.atlassian.net/browse/SFS-2918)
## What's the purpose of this pull request? Replace `storeConfig.seo.titleTemplate` usage with values provided by the hCMS so page titles remain configurable via content, while keeping `discovery.config.js` as fallback to avoid breaking changes. ## How it works? - Reads `titleTemplate` directly from `settings.seo` (hCMS) on Home and Landing pages. - Keeps a fallback to the page title when the template is not present. - Exposes the `titleTemplate` field in the hCMS schema and updates `PageContentType`. ## How to test it? - Publish or edit a page in hCMS setting `settings.seo.titleTemplate`. - Open the corresponding page and confirm the rendered title follows the configured template. <img width="563" height="360" alt="Captura de Tela 2025-11-12 às 17 39 05" src="https://github.com/user-attachments/assets/39ae34c8-def5-48ed-94b3-320367e31d08" /> <img width="489" height="412" alt="Captura de Tela 2025-11-12 às 17 44 29" src="https://github.com/user-attachments/assets/c4eb64f5-7d28-417e-992d-ccd20dc4a159" /> ### Starters Deploy Preview URL Preview: https://brandless-cma5xay4001f6dn4xjwato8b4-7wpvceise.b.vtex.app/ ## References [Jira task](https://vtex-dev.atlassian.net/jira/software/c/projects/SFS/boards/1051?selectedIssue=SFS-2920)
8d847df to
9bbc764
Compare
## What's the purpose of this pull request? Currently, the "Min" and "Max" labels and error messages in the FilterFacetRange component are hardcoded in the code, preventing customization via hCMS. This PR enables editing these labels and messages through hCMS, allowing store owners to customize the component without code changes. ## How it works? - Adds optional props `minLabel`, `maxLabel`, `minPriceGreaterThanMaxErrorMessage` and `maxPriceSmallerThanMinErrorMessage` to the `PriceRange` component - Extends `FilterFacetRange` to accept and pass through these props - Creates a new `filters` section in the hCMS schema (`content-types.json`) with configurations for `filterFacetRange` - Connects `FilterDesktop` and `FilterSlider` to read hCMS configurations and pass them to the component Default values are maintained for backward compatibility if no configuration is defined in hCMS. ## How to test it? 1. Access hCMS and navigate to the "Filters" section in global settings 2. Configure values for `filterFacetRange`: - `minLabel`: Label for the minimum field (e.g., "Min", "From") - `maxLabel`: Label for the maximum field (e.g., "Max", "To") - `minPriceGreaterThanMaxErrorMessage`: Error message when minimum > maximum - `maxPriceSmallerThanMinErrorMessage`: Error message when maximum < minimum 3. Access a PLP/Search page that has a range filter (e.g., price) 4. Verify that custom labels appear in the input fields 5. Test validation by entering invalid values and verify that custom error messages appear <img width="1238" height="867" alt="Captura de Tela 2025-11-24 às 10 10 54" src="https://github.com/user-attachments/assets/42c01133-20b6-4e2e-b794-9909cca47f0e" /> <img width="549" height="482" alt="Captura de Tela 2025-11-24 às 10 25 10" src="https://github.com/user-attachments/assets/a244a7c7-b587-4476-b1d2-2bc1b8dfd88a" /> ### Starters Deploy Preview [Preview](https://brandless-cma5xay4001f6dn4xjwato8b4-8zqdtxg3t.b.vtex.app/apparel?category-1=apparel&fuzzy=0&operator=and&price=359.00-to-1347.00&facets=category-1%2Cfuzzy%2Coperator%2Cprice&sort=score_desc&page=0) ## References - Task: [SFS-2923](https://vtex-dev.atlassian.net/jira/software/c/projects/SFS/boards/1051?selectedIssue=SFS-2923) - Enable FilterFacetRange labels content in hCMS [SFS-2923]: https://vtex-dev.atlassian.net/browse/SFS-2923?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ --------- Co-authored-by: Larícia Mota <laricia.mota@vtex.com.br>
## What's the purpose of this pull request? Currently, the search submit button's `aria-label` is hardcoded as "Submit Search" in the `SearchInput` component code. This PR enables the configuration of the search submit button's `aria-label` through hCMS, allowing editors to customize the text as needed. ## How it works? This PR adds a new `submitButtonAriaLabel` field to the Navbar's `searchInput` configuration in hCMS. The field allows editors to configure the `aria-label` text for the search submit button. When not configured, the default value "Submit Search" is maintained to ensure compatibility with existing implementations. ## How to test it? <img width="653" height="588" alt="Captura de Tela 2025-11-25 às 13 44 34" src="https://github.com/user-attachments/assets/e365d088-2cd0-4152-bb96-8627e9705459" /> <img width="913" height="739" alt="Captura de Tela 2025-11-25 às 13 47 46" src="https://github.com/user-attachments/assets/a82d4ad0-4428-4a3b-9557-6c1217921155" /> ### Starters Deploy Preview [Preview](https://sfj-4410414--brandless.preview.vtex.app/) <!--- Add a link to a deploy preview from `starter.store` with this branch being used. ---> ## References - Task: [SFS-2958](https://vtex-dev.atlassian.net/jira/software/c/projects/SFS/boards/1051?selectedIssue=SFS-2958) [SFS-2958]: https://vtex-dev.atlassian.net/browse/SFS-2958?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ --------- Co-authored-by: Fanny Chien <fanny.chien@vtex.com>
## What's the purpose of this pull request? Add the loading labels to hCMS so they can be editable. We need them there so they can be translated through the CMS.⚠️ Breaking change: there are no more hardcoded labels, it necessarily has to come through CMS. This PR will be merged in the `feat/multilanguage` feature branch, which will be available only in the next faststore major version. ## How it works? It was hardcoded, so adding it to the hCMS schema allows it to be editable. There were a lot of places with a loading label hardcoded, I've fixed those in this PR: - Label "Loading...": - Product Details - Search Dropdown - AddToCartLoadingSkeleton - Checkout page - Label "loading": - OutOfStock - Label "...": - RegionModal - RegionPopover - RegionSlider ## How to test it? Sync hCMS, publish all pages/content-types related: Global sections (Navbar), Global settings (Loading and Regionalization) and the PDP (ProductDetails section). Then, navigate through the pages and watch for the use cases. ### hCMS | Global sections | Global sections settings | PDP | | ---- | ---- | ---- | | Navbar <img width="1006" height="541" alt="hCMS - Global Sections - Navbar" src="https://github.com/user-attachments/assets/21cb8198-e9db-49aa-a2ba-9f4915e4fd14" /> | Loading <img width="559" height="598" alt="hCMS - Global Sections - Settings" src="https://github.com/user-attachments/assets/09a7ec61-c9e5-4c9a-8e50-000d5d9accc0" /> | ProductDetails <img width="685" height="708" alt="hCMS - ProductDetails" src="https://github.com/user-attachments/assets/c8ff2389-2cb5-42d9-897a-5a583d7febaf" /> | | | Regionalization <img width="738" height="823" alt="hCMS - Global Sections - Settings - Regionalization" src="https://github.com/user-attachments/assets/88786515-24f7-4e1b-a191-cb9b59605988" /> | | ### Preview | PDP | Delivery Promise | Search dropdown (Navbar) | Checkout Page | | ---- | ---- | ---- | ---- | | <img width="1807" height="521" alt="ProductDetails - isClientOfferEnabled isValidating" src="https://github.com/user-attachments/assets/9c1adab6-7e4c-4917-9129-51d830d4d0fe" /> condition: `isClientOfferEnabled && isValidating`| RegionModal <img width="409" height="255" alt="RegionModal" src="https://github.com/user-attachments/assets/0a61b40e-9073-44db-8709-cec9615aa639" /> | <img width="890" height="113" alt="SearchDropdown" src="https://github.com/user-attachments/assets/50b27573-0cea-4c8d-85de-de3c95024f4f" /> | <img width="455" height="476" alt="Checkout page" src="https://github.com/user-attachments/assets/259d8354-debd-4e08-aef1-587908a35928" /> | | <img width="1560" height="715" alt="ProductDetailsSettings - isValidating" src="https://github.com/user-attachments/assets/2fb74be3-d413-48a0-80e3-b2ed3e5c24f6" /> condition: `isValidating` | RegionPopover <img width="376" height="280" alt="RegionPopover" src="https://github.com/user-attachments/assets/79eeb3ca-48cc-445b-aec1-5ebd0ddf8261" /> | | | | <img width="1400" height="447" alt="PDP - OutOfStock" src="https://github.com/user-attachments/assets/b7fb5448-9bb7-45e3-99f9-7bc39b6e9679" /> condition: using `OutOfStock` component | RegionSlider <img width="365" height="244" alt="RegionSlider" src="https://github.com/user-attachments/assets/3c9c96bf-674e-4c8b-a536-f1aafcc43d4a" /> | | | ### Starters Deploy Preview - https://brandless-cma5xay4001f6dn4xjwato8b4-9le7ry87q.b.vtex.app/ ([PR](vtex-sites/brandless.store#118)) - To test DP related sections: https://vendemo-cm9sir9v900u7z6llkl62l70j-87xw27y77.b.vtex.app/ ([PR](dp-faststore-org/vendemo-dp#114)) ## References - [Jira task](https://vtex-dev.atlassian.net/browse/SFS-2922)
## What's the purpose of this pull request? - Adds SDK payload temp to test The `locales-setting.json` is a temp file that mocks the payload that the `faststore-sdk` will return with the account's available locales and settings. - Handle config from path locales strategy: extract available locales from `locales-setting.json` ## How it works? Set `next.config.js` to support url Path locales, cases like https://www.store.com/en-CA, https://www.store.com/pt-BR ## How to test it? 1. Run the application locally 2. When navigating to `http://localhost:3000` the defaultLocale should be set. - check the `<html lang>` attribute. It should be `pt-BR` <img width="1362" height="216" alt="image" src="https://github.com/user-attachments/assets/764bf9dd-3b46-43de-9b0a-f2c534cb437e" /> 3. Then, try navigating to other mapped locales, and check the `lang` atribute. - http://localhost:3000/en-CA <img width="1233" height="301" alt="image" src="https://github.com/user-attachments/assets/8e6ab112-181a-4d81-841c-877bb91b0d62" /> - http://localhost:3000/en-US <img width="1277" height="328" alt="image" src="https://github.com/user-attachments/assets/50a3e4e2-36d0-4ffd-af9a-94576c037fae" /> - http://localhost:3000/pt-BR - http://localhost:3000/fr-CA - http://localhost:3000/it-IT All the paths listed above should be valid paths. ### Starters Deploy Preview ## References [Jira Task](https://vtex-dev.atlassian.net/jira/software/c/projects/SFS/boards/1051?selectedIssue=SFS-2965) https://nextjs.org/docs/pages/guides/internationalization
## What's the purpose of this pull request? Add the ProductDescription aria-label to hCMS so it can be editable. We need it there so it can be translated through the CMS. ## How it works? It was hardcoded, so adding it to the hCMS schema allows it to be editable. ## How to test it? 1. Run this branch locally or use this [preview link](https://brandless-cma5xay4001f6dn4xjwato8b4-jb9xu2lh7.b.vtex.app/adidas-womens-microdot-polo-night-indigo-70/p) 2. Navigate to a PDP Check if the Description accordion has a custom aria label different than `Product Description Content` <img width="1536" height="164" alt="image" src="https://github.com/user-attachments/assets/55e89d2f-5d00-45ed-86ba-f23e41b60f55" /> 3. Or access the cms in admin and try changing the content and publish <img width="643" height="539" alt="image" src="https://github.com/user-attachments/assets/58c0765d-b794-4227-8512-3da32ba6c550" /> ### Starters Deploy Preview [preview link](https://brandless-cma5xay4001f6dn4xjwato8b4-jb9xu2lh7.b.vtex.app/adidas-womens-microdot-polo-night-indigo-70/p) ## References - [Jira task](https://vtex-dev.atlassian.net/browse/SFS-2979)
## What's the purpose of this pull request? Update the i18n next config to handle subdomain locales strategy. ## How it works? The function `buildI18nDomains` adds the binding URLs domains in the domains array (i18n next config) if there is no path in the URL. ## How to test it? Test that the path strategy continues working by accessing the locales paths, like `/pt-BR`. To test the domains strategy I configured some routing test domains in `/etc/hosts`, to do that you can follow these steps: - In the terminal run `sudo vi /etc/hosts` - Then edit to add the following config: ``` 127.0.0.1 brandless.fast.store.com.br 127.0.0.1 canada.brandless.fast.store 127.0.0.1 brandless.fast.store.com 127.0.0.1 brandless.fast.store ``` - Save it and you'll have something like: <img width="467" height="272" alt="Screenshot 2025-12-04 at 18 21 45" src="https://github.com/user-attachments/assets/4ca17234-0f9f-476e-a441-56b657261ef5" /> Then, run the core and you can test paths and subdomains strategies freely. | Path | Subdomain | | ---- | ---- | | <img width="1496" height="659" alt="path - pt-BR" src="https://github.com/user-attachments/assets/9308dbef-e5a6-43b2-8ef9-a5aa8baa3385" /> | <img width="1487" height="616" alt="domain - com br" src="https://github.com/user-attachments/assets/c4010a17-aa12-4768-bcd3-bba66eae7843" /> | | <img width="1465" height="619" alt="path - it-IT" src="https://github.com/user-attachments/assets/160a2495-7bca-4c7d-a99f-bf2eacd653a3" /> | <img width="1470" height="639" alt="domain - canada" src="https://github.com/user-attachments/assets/05c713ee-5eaf-4985-8e20-870221a1198c" /> | | <img width="1473" height="619" alt="path - en-CA" src="https://github.com/user-attachments/assets/264eb405-4341-440f-8a19-d2d2c4c4a473" /> | <img width="1466" height="638" alt="domain - com" src="https://github.com/user-attachments/assets/0bf569bf-e8a1-4f66-a4c0-1d606203a60b" /> | | <img width="1489" height="616" alt="path - en-US" src="https://github.com/user-attachments/assets/36d236f7-99e2-4cbf-ac37-ed188451ba46" /> | | ### Starters Deploy Preview <!--- Add a link to a deploy preview from `starter.store` with this branch being used. ---> <!--- Tip: You can get an installable version of this branch from the CodeSandbox generated when this PR is created. ---> ## References - [Jira task](https://vtex-dev.atlassian.net/browse/SFS-2966) - [Slack thread](https://vtex.slack.com/archives/C09CZGYTXEE/p1764883650666369)
## What's the purpose of this pull request? - Adds `i18nButton` / enables via hCMS - Adds `Globe` icon - This button will display the current locale and currency (default version) - This button will enable the user to change settings (locale/currency) note: Adding the `AGENTS.md` file ([ref](https://agents.md)), this is specifically written for AI assistants to understand the codebase quickly and provide better help. I created it based on the [FastStore Components Implementation Guidelines doc](https://docs.google.com/document/d/1jTDQAkdqZQfe9fkDDI9V74JVgCg1GPktdYArW-UDpTo/edit?tab=t.0#heading=h.tglo77yl0lf5) and more focused on the components implementation to test. |desktop|mobile| |-|-| |<img width="723" height="79" alt="image" src="https://github.com/user-attachments/assets/0b516721-7efb-40cb-ba09-13c026e4554d" />|<img width="352" height="761" alt="image" src="https://github.com/user-attachments/assets/3e0a61d8-24a7-459a-80ac-9b83165f73e2" />| ## How to test it? - Enables the button via hCMS, and publish (it's already enabled in the brandiess acc - if you don't see this section, you might need to run cms sync and publish again) <img width="500" height="841" alt="image" src="https://github.com/user-attachments/assets/86a07ffe-bd82-43c9-938d-27f8e8e0a2f6" /> - [desktop] The `i18nButton` should appear in the `Navbar` between the SearchInput and SignIn button. - [mobile] The `i18nButton` should appear in the `NavbarSlider` below the SignIn button. ### Starters Deploy Preview [preview link](https://brandless-cma5xay4001f6dn4xjwato8b4-r6ryou7rq.b.vtex.app) ## References [Jira Task](https://vtex-dev.atlassian.net/jira/software/c/projects/SFS/boards/1051?selectedIssue=SFS-2888) --------- Co-authored-by: Leandro Rodrigues <leandro.rodrigues@vtex.com>
## What's the purpose of this pull request? Adds a new CLI command `generate-i18n` that fetches store i18n configurations (locales, regions, currencies) from the FastStore SDK and creates/updates the configuration in `discovery.config.default.js`. ## How it works? 1. Searches for `discovery.config.default.js` (root, `.faststore`, or `--config` path) 2. Validates environment variables (`VTEX_ACCOUNT`, `FS_DISCOVERY_APP_KEY`, `FS_DISCOVERY_APP_TOKEN`) 3. Fetches i18n config from FastStore SDK 4. Merges with existing config **Note:** Currently uses `mockedSettings` as the SDK returns old structure. When SDK is updated, uncomment the real API call. ## How to test it? **Prerequisites:** Set `VTEX_ACCOUNT`, `FS_DISCOVERY_APP_KEY`, `FS_DISCOVERY_APP_TOKEN` ```bash node packages/cli/bin/run.js generate-i18n ./packages/core ``` Verify that `discovery.config.default.js` contains the `i18n` section and existing properties are preserved. ## References - **JIRA:** [SFS-2964](https://vtex-dev.atlassian.net/jira/software/c/projects/SFS/boards/1051?selectedIssue=SFS-2964) - Similar pattern: `cache-graphql.ts` [SFS-2964]: https://vtex-dev.atlassian.net/browse/SFS-2964?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
## What's the purpose of this pull request? Implements a locale/hostname validation system that ensures URLs match the correct locale configuration based on the hostname. The feature prevents invalid locale/hostname combinations and returns appropriate 404 responses when configurations don't match. We want to support multiple locales and they can be configured with different URL structures: - **Subdomain bindings**: A hostname dedicated to a locale (e.g., `canada.brandless.fast.store` → `fr-CA`) - **Path-based bindings**: A hostname that serves multiple locales via paths (e.g., `brandless.fast.store/en-US`, `brandless.fast.store/it-IT`) Without validation, users could access invalid combinations like: - `brandless.fast.store/fr-CA/products` → should be 404, as `fr-CA` is only bound to `canada.brandless.fast.store` - `canada.brandless.fast.store/en-US/products` → should be 404, as `en-US` is not bound to this hostname ## How it works? ### SSR & Client-Side Validation This implementation handles both Server-Side Rendered (SSR) and Static Site Generated (SSG) pages: #### SSR Pages (e.g., `/pvt/account/*`) - **When**: Page uses `getServerSideProps` - **Where**: Server-side before rendering - **How**: `withLocaleValidationSSR` HOC wraps `getServerSideProps` - **Result**: Returns `notFound: true` → Next.js serves 404 page - **Benefit**: User never sees the invalid page, better SEO #### SSG Pages (e.g., PLPs, PDPs) - **When**: Page uses `getStaticProps` (pre-generated at build time) - **Where**: Client-side after hydration - **How**: `useEffect` in `_app.tsx` validates after mount - **Result**: Redirects to `/404` with original path in query string - **Trade-off**: Page loads before redirect, but SSG pages remain fast ps.: The same solution from SSR doesn't work on SSG because we don't have access to hostname on `getStaticProps`. ps2.: Middleware would work for this use case, but we decided to not use it to be cost efficient. #### Validation logic 1. **Localhost bypass**: Allows all locales on `localhost` and `127.0.0.1` for development tests 2. **Binding check**: Verifies if the locale has a binding for the hostname - Checks all bindings for the given locale - Matches if `binding.url` hostname equals the request hostname ## How to test it? Configure your `etc/hosts` like explained in the previous [PR](#3143), then test navigating through the store and changing domains/paths. In the discovery.config.default, put `enableFaststoreMyAccount` as `true` to test the `/pvt/account` pages. ### Example Scenarios (based on mock) #### Valid Combinations ✅ | URL | Type | Result | | -------------------------------------------- | ---------------- | ------- | | `brandless.fast.store:3000/pt-BR/apparel` | Path-based | ✅ Valid | | `brandless.fast.store.com.br:3000/pt-BR` | Subdomain | ✅ Valid | | `canada.brandless.fast.store:3000/fr-CA` | Subdomain | ✅ Valid | | `brandless.fast.store:3000/en-US/pvt/account` | Path-based (SSR) | ✅ Valid | #### Invalid Combinations ❌ | URL | Why Invalid | Result | | ----------------------------------------------- | ------------------------------------ | -------------- | | `brandless.fast.store:3000/fr-CA` | fr-CA only bound to canada subdomain | ❌ 404 (Client) | | `canada.brandless.fast.store:3000/en-US/apparel` | en-US not bound to canada subdomain | ❌ 404 (Client) | | `brandless.fast.store.com:3000/pt-BR/apparel` | pt-BR not bound to .com | ❌ 404 (Client) | | `canada.brandless.fast.store:3000/pt-BR/pvt/account` | pt-BR not bound to canada | ❌ 404 (SSR) | ## References - [Jira task](https://vtex-dev.atlassian.net/browse/SFS-2990) - Slack threads ([1](https://vtex.slack.com/archives/C09CZGYTXEE/p1764883650666369), [2](https://vtex.slack.com/archives/C09CZGYTXEE/p1765564641414739))
## What's the purpose of this pull request? - Undo styles change for i18nButton , keep the button default. - Changes button on navbar desktop to 40px as design tem asked. note: We should introduce later a new size variant `medium` (40px) to `Button` component. Then we can remove this change and update the buttons accordingly. ## How it works? The i18nButton should have the same default button style. ## How to test it? 1. Run the application and check in the Navbar - navbar buttons on desktop should have height = 40px <img width="861" height="114" alt="image" src="https://github.com/user-attachments/assets/4264cc0b-d490-4640-b1c6-5c3fd5392a41" /> - i18n button with default style |before|now| |-|-| |<img width="549" height="93" alt="image" src="https://github.com/user-attachments/assets/fe0a2c4d-8b12-4eb5-9d63-70daea552d81" />|<img width="708" height="80" alt="image" src="https://github.com/user-attachments/assets/6da060e7-87a3-4251-8b86-5117bc2e4d5d" />|
…3162) ## What's the purpose of this pull request? The `generate-i18n` command was using temporary mocked data exported from the production code. This PR integrates the real FastStore SDK `locales()` method, removing the hardcoded mock and making the command fetch actual i18n configuration. ## How it works? This PR makes the following changes: - **Removes mocked data from production code**: The `mockedSettings` constant was exported from `generate-i18n.ts` and has been removed - **Integrates real SDK method**: Uncommented and updated the FastStore SDK integration to use the `locales()` method (updated from the old `settings()` method) - **Updates test suite**: Moved the `mockedSettings` to the test file and properly mocked the SDK's `locales()` method to return test data - **Removes `locales-setting.jsons` mock data references and uses i18n settings instead. The command now correctly fetches real i18n configuration (locales, regions, currencies) from the VTEX platform when executed with proper credentials. ## How to test it? 1. Set up the required environment variables 2. Run `node packages/cli/bin/run generate-i18n ./packages/core` 3. Verify that the `discovery.config.default.js` file is updated with i18n configuration fetched from the SDK 4. Verify if the path strategy continues working by accessing the locales paths, like `/pt-BR`. 5. Verify if the subdomain strategy continues working by accessing the urls with locale subdomain ### Starters Deploy Preview N/A - This is a CLI-only change ## References [Jira Task] https://vtex-dev.atlassian.net/jira/software/c/projects/SFS/boards/1055?selectedIssue=SFS-2995 --------- Co-authored-by: fanny <fanny.chien@vtex.com>
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing touches🧪 Generate unit tests (beta)
Tip Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord. 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. Comment |
## What's the purpose of this pull request? This PR implements a new `I18nSelector` component that allows users to select their preferred language and currency. The component provides a seamless experience across devices, using a Popover on desktop and a SlideOver on mobile. All UI texts are configurable through the CMS, making it easy for store administrators to customize the experience for their audience. ## How it works? The implementation consists of several key components and enhancements: ### Core Components 1. **I18nSelector Component** (`packages/core/src/components/i18n/I18nSelector/`) - Responsive component that switches between Popover (desktop) and SlideOver (mobile) based on screen size - Manages language and currency selection state - Receives all content (languages, currencies, labels, descriptions) via props - Includes a reusable `I18nSelectorContent` subcomponent for the form fields 2. **I18nButton Component** (updated) - Button that triggers the I18nSelector - Displays current locale and currency (e.g., "EN/BRL") - Receives configuration from CMS via Navbar section - Uses default English texts when CMS values are not provided ### Library Enhancements 3. **Popover Component** (enhanced) - Added optional portal rendering support via `usePortal` prop (default: `false`) - Added `wrapperProps` for customizing the portal wrapper div - Uses `position: fixed` when portal is enabled for accurate viewport positioning - Maintains backward compatibility with existing implementations 4. **SlideOver Component** (enhanced) - Added new `bottomSide` direction for bottom-to-top animations - Supports vertical slide animations with proper CSS transitions - Works seamlessly with existing `leftSide` and `rightSide` directions ### CMS Integration 5. **CMS Configuration** (`sections.json`) - Added `i18nSelector` object in Navbar navigation schema - Configurable fields: `title`, `languageLabel`, `currencyLabel`, `description`, `saveLabel` - All fields have English defaults - Separate from `i18nButton` configuration for better organization ### User Experience - **Desktop**: Popover appears below the I18nButton with form fields and save button - **Mobile**: SlideOver slides up from the bottom with header, content, and footer ## How to test it? Link Preview ### Starters Deploy Preview <!--- Add a link to a deploy preview from `starter.store` with this branch being used. ---> <!-- Link will be added after preview is generated --> ## References - **Jira Issue**: [SFS-2889](https://vtex-dev.atlassian.net/jira/software/c/projects/SFS/boards/1051?selectedIssue=SFS-2889) [SFS-2889]: https://vtex-dev.atlassian.net/browse/SFS-2889?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
## What's the purpose of this pull request? Adds a feature flag to enable localization functionality. ## How it works? This PR introduces a `localization.enabled` feature flag in the discovery.config file that controls localization functionality: - **When `localization.enabled === true`**: - The `generate-i18n` command is executed during build/dev time to retrieve settings from the FastStore SDK - Store settings (locale, currency, region, channel) are initialized using data from the SDK - The `useLocaleValidation` hook runs in `_app.tsx` to validate locale bindings - **When `localization.enabled === false` or the flag is missing** (default behavior): - The `generate-i18n` command is skipped during build/dev - Store settings use static values from discovery.config (session: currency, locale, channel) - The `useLocaleValidation` hook is skipped - Backward compatibility is fully maintained **Implementation details:** - Added `localization.enabled: false` flag in `discovery.config.default.js` - Modified `build.ts` and `dev.ts` commands to conditionally execute `generate-i18n` - Updated `useLocaleValidation` hook to check the flag before running validation - Extracted `islocalizationEnabled` utility function to `packages/cli/src/utils/config.ts` for reusability ## How to test it? **Note:** These instructions refer to testing FastStore within a store. **Example:** Brandless store (our test store for multi-language) ### Test with localization enabled: 1. Install the package generated by codesandbox: ```json "@faststore/cli": "https://pkg.csb.dev/vtex/faststore/commit/bf4e9e5a/@faststore/cli" ``` 2. Add the flag to your `discovery.config.js`: ```js localization: { enabled: true, }, ``` 3. Ensure you have VTEX credentials set (VTEX_ACCOUNT, FS_DISCOVERY_APP_KEY, FS_DISCOVERY_APP_TOKEN) 4. Run the build or dev command: ```bash yarn build # or yarn dev ``` 5. Verify that: - `generate-i18n` command is executed ### Test with localization disabled (default behavior): 1. Install the package generated by codesandbox: ```json "@faststore/cli": "https://pkg.csb.dev/vtex/faststore/commit/bf4e9e5a/@faststore/cli" ``` 2. Either don't add the flag, or explicitly set: ```js localization: { enabled: false, }, ``` 3. Run the build or dev command: ```bash yarn build # or yarn dev ``` 4. Verify that: - `generate-i18n` command is NOT executed - Store uses static session settings from discovery.config - No locale validation errors occur ### Starters Deploy Preview N/A ## References - Related ticket: [SFS-2996](https://vtex-dev.atlassian.net/browse/SFS-2996) - Discussion thread: https://vtex.slack.com/archives/C09CZGYTXEE/p1764613981678879 [SFS-2996]: https://vtex-dev.atlassian.net/browse/SFS-2996?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ --------- Co-authored-by: Fanny Chien <fanny.chien@vtex.com>
# testing In order to test the i18n config on the discovery.config file should use localhost to hostname to test it. _You could also change your hosts file to add the hostname redirect to localhost_
## What's the purpose of this pull request? This PR consolidates all localization-related configuration into a single `localization` object in the discovery.config file, instead of having `i18n` settings at the root level alongside `localization.enabled`. --------- Co-authored-by: Fanny Chien <fanny.chien@vtex.com>
## What's the purpose of this pull request? This PR implements the logic for the localization binding selector. Merchants need to support multiple language/currency combinations (bindings) with different sales channels. This feature provides the logic layer that enables users to switch between these bindings dynamically. ## How it works? ### Core Components **1. Hook: `useBindingSelector`** - Manages state and orchestrates the binding selection flow - Pre-selects current locale and currency from session - Provides `languages` and `currencies` as `Record<string, string>` format ready for the selector UI component - Handles locale changes with automatic currency validation and adjustment - Validates selections before redirecting to the resolved binding URL **2. Utility: `buildLanguageOptions`** - Disambiguates languages when multiple locales share the same language name - Example: Portuguese appears as "Portuguese (BR)" and "Portuguese (PT)", while unique languages like "English" display without region code **3. Utility: `getCurrenciesForLocale`** - Extracts unique currency codes available for a given locale **4. Utility: `resolveBinding`** - Resolves the correct binding when multiple bindings exist for the same locale+currency combination - Applies `isDefault` as a tie-breaker for deterministic selection **5. Utility: `isValidUrl`** - Validates binding URLs before redirect to prevent errors ### Logic Flow 1. **Initial State**: Hook pre-selects current locale and currency from session 2. **Language Selection**: User selects locale → currencies are filtered to show only available options 3. **Currency Handling**: - If selected currency is available in new locale → keep it selected - If new locale has only one currency → auto-select it - If currency is unavailable → clear selection and show available options 4. **Validation**: Both locale and currency must be selected, with no errors 5. **Save**: Resolves binding, validates URL, and redirects user ## How to test it? Check that the options in the selector match the bindings saved on discovery.config Examples using the `brandless` account configuration: <img width="353" height="340" alt="Screenshot 2026-01-15 at 08 15 44" src="https://github.com/user-attachments/assets/e500d2d0-37fb-413e-b7f6-705e1b7054c6" /> <img width="349" height="374" alt="Screenshot 2026-01-15 at 08 15 36" src="https://github.com/user-attachments/assets/650b1353-0b16-4193-8aa9-e42f3d43e026" /> https://github.com/user-attachments/assets/9f06bd1a-f969-4ccc-b38b-a1d280024a13 ### Starters Deploy Preview <!--- Add a link to a deploy preview from `starter.store` with this branch being used. ---> <!--- Tip: You can get an installable version of this branch from the CodeSandbox generated when this PR is created. ---> ## References - [Jira task](https://vtex-dev.atlassian.net/browse/SFS-2978) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added language and currency selector modal in the navigation bar with customizable labels and descriptions * Extended slide-over component to support bottom positioning in addition to left and right * Enhanced popover positioning capabilities * **Style** * Added styling for the language/currency selector to support responsive desktop and mobile layouts <sub>✏️ Tip: You can customize this high-level summary in your review settings.</sub> <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Leandro Rodrigues <leandro.rodrigues@vtex.com>
## What's the purpose of this pull request? Change `I18nButton` and `I18nSelector` to `LocalizationButton` and `LocalizationSelector`. ## How it works? Changed the components, styles and CMS sections names. ## How to test it? I've synced with `brandless` account and published the Global Sections. ### Starters Deploy Preview <!--- Add a link to a deploy preview from `starter.store` with this branch being used. ---> <!--- Tip: You can get an installable version of this branch from the CodeSandbox generated when this PR is created. ---> ## References - Slack threads: [[1](https://vtex.slack.com/archives/C09CZGYTXEE/p1768401217496629)] and [[2](https://vtex.slack.com/archives/C09CZGYTXEE/p1768575065477709)] <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Refactor** * Renamed Internationalization terminology to Localization throughout the user interface for improved clarity and consistency. Updated button labels, selector components, and navigation elements to reflect the new naming convention. <sub>✏️ Tip: You can customize this high-level summary in your review settings.</sub> <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Leandro Rodrigues <leandro.rodrigues@vtex.com>
… LocalizationButton (#3181) ## What's the purpose of this pull request? Don't display `LocalizationButton` if localization flag is not enabled in discovery.config. ## How to test it? 1. Set `localization.enabled` to `false` ``` localization: { enabled: false, defaultLocale: 'pt-BR', .... } ``` 2. Localization button shouldn't appear. <img width="1276" height="450" alt="image" src="https://github.com/user-attachments/assets/329255f4-d28d-41be-873c-ac19fdddb194" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Refactor** * Enhanced localization feature control with improved gating logic across navigation components. * Localization button now respects combined feature flag and availability conditions before rendering in both desktop and mobile views. * Streamlined localization state management with consistent enable/disable checks. <sub>✏️ Tip: You can customize this high-level summary in your review settings.</sub> <!-- end of auto-generated comment: release notes by coderabbit.ai -->
## What's the purpose of this pull request? This PR removes hardcoded messages, ensuring that all default messages are centralized in CMS configuration files (`sections.json` and `content-types.json`). This enables better localization support and allows store owners to customize all UI messages through the CMS without requiring code changes.⚠️ Breaking change: the messages necessarily have to come through CMS. This PR will be merged in the feat/multilanguage feature branch, which will be available only in the next faststore major version. ## How it works? In each commit I have fixed an specific part to make review process easier, then I'd recommend review per commit. Some I've only removed the hardcoded message because its default was already present in the CMS files, and others I had to also add the default in the CMS file. ### Key Changes: **Components updated:** - Filter components (FilterSlider, FilterDesktop, FilterDeliveryMethodFacet) - Region components (RegionSlider, RegionPopover) - **Cart**: EmptyCart (title, buttonLabel) - **Product**: ProductCard, ProductCardContent (buttonLabel, outOfStockLabel, includeTaxesLabel, sponsoredLabel), ProductDetailsSettings (buyButtonTitle) - **Common**: Breadcrumb (alt, icon), Footer (logoLink defaults), Navbar (collapseSearchAriaLabel) - **Search**: SearchProductItem (outOfStockLabel in quickOrderSettings), SearchInput, SearchTop, SearchHistory - EmptyGallery - Hooks (useDeliveryPromise, useShippingSimulation) - PickupPointCards **Components intentionally skipped:** - MyAccount-related: would increase a lot the changes in this PR, I'll create a task for that - OutOfStock: component not currently in use - PreviewTag: it's not a store component ## How to test it? Sync CMS changes, publish the affected pages and check the messages appear. ### Starters Deploy Preview <!-- Add deploy preview link here --> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Search history and top search titles are now configurable in the navbar and search UI. * Empty cart title and button text are now configurable. * Shipping postal-code error message can be customized. * **Improvements** * Numerous UI labels (buttons, breadcrumbs, delivery/filter labels, product/stock texts) now source configurable defaults from CMS, enabling broader store text customization and regionalization. <sub>✏️ Tip: You can customize this high-level summary in your review settings.</sub> <!-- end of auto-generated comment: release notes by coderabbit.ai -->
## What's the purpose of this pull request? Add **custom path support for i18n** in FastStore stores: in addition to Next.js canonical paths (`/pt-BR`, `/en-US`), stores can now support URLs like `/america/fr/produto/p` and `/europe/it/apparel`, defined by **localization bindings** in `discovery.config`. The middleware rewrites these URLs to the format Next.js i18n expects, and internal links (Link, ProductCard, Hero, etc.) automatically get the custom path prefix when the user is on a customized route. ## How it works? ### Middleware (`packages/core/src/middleware.ts`) - Runs only when `storeConfig.localization?.enabled` is `true`. - **Rewrite rules** are generated dynamically from bindings in `discovery.config`: for each binding whose URL has a custom path (e.g. `https://store.com/america/fr`), a rule is created that: - matches the request path (e.g. `/america/fr`, `/america/fr/produto/p`); - rewrites internally to the canonical locale path (e.g. `/fr-CA`, `/fr-CA/produto/p`). - Paths are ordered by length (longest first) to avoid incorrect matches. - Hostname validation per rule exists in the code but is disabled (TODO) to ease testing on localhost; it can be re-enabled when needed. - The matcher excludes `api`, `_next/static`, `_next/image`, `favicon.ico`, and static assets. ### Custom path utilities (`packages/core/src/utils/customPaths.ts`) - **`isCustomPath(url)`** – Returns whether the URL uses a custom path (e.g. `/america/fr`) instead of a canonical one (`/pt-BR`). - **`getCustomPathsFromBindings()`** – Reads custom paths from localization bindings; the result is **cached** so the loop is not repeated on every link. - **`addCustomPathPrefix(link, currentPathname)`** – For internal links (`/apparel`), adds the current custom path prefix when the user is on a customized route (e.g. on `/america/fr` → `/apparel` becomes `/america/fr/apparel`). Does not change external links or links that already have the prefix. ### Where the prefix is applied to links - **`Link` (core)** – Uses `addCustomPathPrefix(href, router.asPath)` for internal links, so all links that go through the core Link component get the prefix when applicable. - **`useProductLink`** – Applies the prefix to the product `href` (`/${slug}/p`), fixing ProductCard links that did not use the core Link. - **Hero** – Applies the prefix to the CTA `link?.url` before passing it to `HeroHeader`, fixing the “See Offers” button (fs-link-button) on customized routes. ### Middleware toggle by localization feature flag (CLI) When the **localization feature flag** (`localization.enabled`) is `false`, the CLI disables the i18n middleware - **`toggleI18nMiddlewareByLocalizationFlag`** (`packages/cli/src/utils/generate.ts`) – Called from **build** and **dev** after the existing localization check and (optional) `generate-i18n` step: - **Flag on**: Ensures `middleware.ts` is present (renames `middleware__I18N_DISABLED.ts` → `middleware.ts` if needed). - **Flag off**: Renames `middleware.ts` → `middleware__I18N_DISABLED.ts` so Next.js does not load or run the i18n middleware. ### Binding URL format in the admin **Binding URLs** must be only the path base, **without** product or page path. E.g.: ✅ `https://store.com/america/fr` ❌ `https://store.com/america/fr/produto/p` If the binding URL includes a product/page path, the middleware treats that entire path as the custom path for that locale and rewrite rules become incorrect. ### Outstanding items (TODOs in code) - Re-enable hostname validation per rule in the middleware when it is no longer necessary to skip it on localhost. - Re-enable or adjust locale validation for subdomain bindings (`useLocaleValidation`); the current validation does not account for custom paths (only hostname + locale). ## How to test it? 1. Ensure `localization.enabled` is `true` in `discovery.config` and that there are bindings with a **custom path** (e.g. `https://yoursite.com/america/fr` for locale `fr-CA`). To generate or refresh locales/bindings from the SDK, run from the **repo root**: ```bash node packages/cli/bin/run.js generate-i18n ./packages/core ``` Requires VTEX credentials: `VTEX_ACCOUNT`, `FS_DISCOVERY_APP_KEY`, and `FS_DISCOVERY_APP_TOKEN`. 2. Start the store (`pnpm dev` in core) and open the custom path, e.g. `http://localhost:3000/america/fr`. 3. Confirm the page loads with the correct locale (e.g. `lang="fr-CA"` on `<html>`). 4. Navigate via header links, hero (“See Offers”), product cards, and other internal links and confirm they keep the prefix (e.g. `/america/fr/technology`, `/america/fr/produto-x/p`). 5. On a canonical route (e.g. `/pt-BR`), confirm links remain without a custom prefix (e.g. `/apparel`, `/produto/p`). 6. Turn off `localization.enabled`, run `pnpm dev` or `pnpm build` again, and confirm the CLI renames `middleware.ts` to `middleware__I18N_DISABLED.ts` (so Next.js does not run the i18n middleware and links do not get a prefix). ### Starters Deploy Preview Preview custom path -> Locale: fr-CA Home with custom path: https://brandless-cma5xay4001f6dn4xjwato8b4-qqih78fto.b.vtex.app/america/fr <!--- Add a link to a deploy preview from `starter.store` with this branch being used. ---> <!--- Tip: You can get an installable version of this branch from the CodeSandbox generated when this PR is created. ---> ## References [Jira task](https://vtex-dev.atlassian.net/jira/software/c/projects/SFS/boards/1051?selectedIssue=SFS-3020) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** - Server-side middleware for automatic locale-based URL rewriting - i18n-aware link resolution applied across UI (links, hero, alerts, product links) - Custom localization path management and prefixing utilities - Build/dev flows now toggle middleware based on the localization setting * **Removed** - Legacy redirects middleware and its redirect lookups * **Refactor** - Removed client-side locale validation in favor of server-side handling * **Tests** - Added comprehensive tests for custom localization path utilities <!-- end of auto-generated comment: release notes by coderabbit.ai -->
## What's the purpose of this pull request? This PR introduces multi-locale support for content fetching via the Content Platform (CP). It enables the store to fetch localized content dynamically based on the user's current locale. https://github.com/user-attachments/assets/9078f73c-879f-4239-b229-2815b18f2550 ## Content Platform Locale Support Updated the CP client version to `@vtex/client-cp: 0.4.0` The `ContentService` now accepts a `locale` parameter that gets passed to the Content Platform client, allowing it to fetch locale-specific content: ``` // packages/core/src/server/content/service.ts private getClientCP(locale?: string): ClientCP { const currentLocale = locale ?? config.localization.defaultLocale return new ClientCP({ tenant: config.api.storeId, locale: currentLocale, // 👈 Locale-aware client }) } ``` ## Key Changes: **Content Platform** - Schema & CMS Updates: Updated `schema.json`, `cms/faststore/components`, and `cms/faststore/pages` with the latest multi-language changes (new localization components and removal of hardcoded labels). - ContentParams: Added locale parameter support. - Routing & Sections: Passed the locale parameter to Pages, GlobalSections, and LandingPage. Note: "My Account" pages were intentionally skipped; a follow-up task will be created for this. 🎗️: When merging the multilanguage branch, run the following in the content account: `vtex content generate-schema cms/faststore/components cms/faststore/pages -o cms/faststore/schema.json -l cms/faststore/base.jsonc`. Current changes are applied only to `brandless` acc. TODO: Testing add a new locale in content platform after default values issues fixed. **Localization Updates** - Some improvements to `useLocalizationConfig.tsx` file: - Fixed `salesChannel` type to avoid duplicate queries. - Atempts to fix race condition with `validateSession` in order to testing the languages-switch content (I'll probably create a task to properly handle this issue) **CLI Localization/CP settings** - Verify when localization is enabled, the contentSource should be "CP" - updates `packages/cli/src/commands/generate-i18n.ts` to reflect this requirement. ## How to test it? Note: There are current limitations being addressed with the CP team. `discovery.config` has been committed with a mock for testing. Setup: 1. In faststore/packages, run pnpm i and pnpm build. 😬 2. Ensure the localization flag is enabled. 3. Run the core locally. 4. Access the [Brandless Admin](https://brandless.myvtex.com/admin/content-platform) to make changes. **Content Switching** You should be seeing the homepage like this: <img width="1419" height="1035" alt="image" src="https://github.com/user-attachments/assets/0beb7b86-889a-4b4e-bb88-639e0be561f6" /> - The default locale is pt-BR. - Switch locales using the UI selector or by appending the locale to the URL. <img width="1403" height="405" alt="image" src="https://github.com/user-attachments/assets/3c33b638-16df-4f9b-be38-a9942e01ea19" /> - Expected Behavior: Content should update based on the locale. If no localized content exists, it should fallback to the default (pt-BR). Here are the list of the pages/content type that you should verify: - Global Section (Avoid changing LocalizationButton settings until we fix the issue - [details] For example: the `Buy now` link has the same content when switching. <img width="1309" height="110" alt="image" src="https://github.com/user-attachments/assets/11be6f1a-80cf-4c41-a126-0536c36463bb" /> <img width="1635" height="669" alt="image" src="https://github.com/user-attachments/assets/e38de113-6847-47ff-a387-6470b3530c85" /> It's correct, because is using the default `Português (Brasil) (Default)` for the link text. You can change it and click in `Salvar na main` <img width="1247" height="894" alt="image" src="https://github.com/user-attachments/assets/8e51cfc9-fb20-45e1-8f15-76eeed4a657c" /> after publishing it, reload the page and verify if the changes were reflected. - Homepage - LandingPage (can try `/teste-landing-page` or change/create a new one) - PDP - PLP (it's breaking because of sortBy section missing in UI/schema - still checking this issue) - Search Page (it's breaking because of `sortBySelector` missing in UI/schema - still checking this issue) (https://github.com/vtex/faststore/pull/3165/changes#r2748069043)) - 404 - 500 **Configuration Validation - Localization/CP settings** in the `discovery.config` file: - Change the contentSource flag to "CMS" or "" while keeping `localization.enabled: true`. ``` contentSource: { type: "", }, localization: { enabled: true, defaultLocale: "pt-BR", .... } ``` Run `node packages/cli/bin/run.js generate-i18n ./packages/core` Expected Behavior: The CLI should throw an error regarding the contentSource requirement. <img width="650" height="187" alt="image" src="https://github.com/user-attachments/assets/1356ca4d-743c-4dee-bca0-4d6902ada4a5" /> ### Starters Deploy Preview [WIP] ### Reference: [Jira Task](https://vtex-dev.atlassian.net/jira/software/c/projects/SFS/boards/1051?selectedIssue=SFS-2892) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * US localization (en‑US + USD) and richer region/locale settings * Scroll-to-top button component * SEO title templates for Home, Landing, PDP, PLP and Search * **Improvements** * Locale-aware content fetching across pages (multi-language support) * Navbar: localization button/selector and improved search labels/titles * Breadcrumb fallback label and Cart sidebar empty-state texts * Product Gallery: new sort options; Product Details: loading/ARIA texts * Component schemas expanded with richer metadata/configuration <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Larícia Mota <laricia.mota@vtex.com.br>
in one of the PR localizationEnabled was removed, but needed.
Addded two test case, one that simulates the running scenarioon on build time (node env) and other simulating browser with different locations to check wether the storeURL is returning the correct one. <img width="780" height="279" alt="image" src="https://github.com/user-attachments/assets/84e82d21-cf2f-4ce0-8f43-3442b813018c" /> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Dynamic store URL resolution applied across the app for SEO, links, logout/redirects and cookie domain handling. * **Refactor** * Replaced static store URL usage with a runtime resolver to ensure consistent, localized URLs. * **Tests** * Added unit and browser tests for store URL resolution and updated test setup to support browser/jsdom scenarios. * **Chores** * Updated development/test tooling and added React test plugin. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Chores** * Added a convenience "build" script alias to streamline the build/type-generation workflow. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
## What's the purpose of this pull request? Avoids duplicated log error message when running `yarn dev`: |Before|After| |-|-| |<img width="663" height="375" alt="image" src="https://github.com/user-attachments/assets/dfc840c6-db26-4df0-832f-ff1884e9ac68" />|<img width="714" height="210" alt="image" src="https://github.com/user-attachments/assets/52b6eb2f-8600-4a28-83f7-07b076b3d778" />| ## How it works? ## How to test it? ### Starters Deploy Preview <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Refactor** * Improved internal configuration handling in CLI build and development commands for more consistent localization settings management. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
## What's the purpose of this pull request? Updates the faststore-sdk version to the latest with isDefault locale [fix](vtex/faststore-sdk#3). It might have been cause some inconsistencies in our testing. ## How it works? We should have only one `isDefault: true` per binding. |Before|After| |-|-| |<img width="493" height="719" alt="image" src="https://github.com/user-attachments/assets/afcda4f6-5b2d-4464-86e4-0cabd9883845" />|<img width="580" height="617" alt="image" src="https://github.com/user-attachments/assets/9bd345bc-e07c-437c-b0d0-d9a9ed46fe68" />| ## How to test it? 1. Run the store locale. 2. run `node packages/cli/bin/run.js generate-i18n ./packages/core ` 3. check the locales setting in discovery.config. For each binding, you should see only one `isDefault:true`. ### Starters Deploy Preview starter preview: https://brandless-cma5xay4001f6dn4xjwato8b4-hk7s7lz52.b.vtex.app/ ## References <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Enhanced locale and currency binding resolution with improved default binding selection for better multi-locale support. * **Chores** * Updated SDK dependencies for improved stability. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
## What's the purpose of this pull request?
Session and segment cookies (`vtex-session` and `vtex-segment`) were not
being updated correctly for custom path bindings like `/europe/it`. The
sales channel and locale remained at default values instead of updating
to the correct binding configuration.
## How it works?
The `matchURLBinding` function in
`packages/core/src/sdk/localization/match-url.ts` only matched URLs
using a locale code regex pattern `/\/(\w{2}-\w{2})\/?/i`. This worked
for locale paths like `/pt-BR` but failed for custom paths like
`/europe/it`.
Updated `matchURLBinding` to:
1. Compare **full pathnames** directly instead of only extracting locale
code patterns
2. Support **path prefix matching** for URLs with additional segments
(e.g., `/europe/it/products` matches binding `/europe/it`)
3. Handle **trailing slashes** properly
4. Support **all binding types**: root domains, locale paths, custom
paths, and subdomains
5. **Refactored to use shared `matchesBindingPath` utility** (cleaner,
more maintainable)
6. **Properly implement development mode** for local testing (allows
port/protocol/hostname mismatch)
## How to test it?
Test different binding types, mainly custom path, which is the one that
had the bug.
After configuring `/etc/hosts` to point those bindings to localhost, go
to the URL configured and check if the session/segment cookies are
correct.
| Binding Type | Example
|--------------|---------|
| Root domain | `https://brandless.myvtex.com` |
| Locale path | `/pt-BR`, `/it-IT`, `/en-US` |
| Custom path | `/europe/it`, `/america/fr`, `/emea-eur` |
| With segments | `/europe/it/products`, `/pt-BR/office` |
| Subdomain | `https://pt.brandless.fast.store` |
### Starters Deploy Preview
<!--- Add a link to a deploy preview from `starter.store` with this
branch being used. --->
<!--- Tip: You can get an installable version of this branch from the
CodeSandbox generated when this PR is created. --->
## References
- [Jira
task](https://vtex-dev.atlassian.net/jira/software/c/projects/SFS/boards/1051?selectedIssue=SFS-3046)
- [Bug
video](https://vtex.slack.com/archives/C09CZGYTXEE/p1770298299914469?thread_ts=1769527956.493009&cid=C09CZGYTXEE)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Improved URL binding so localization detection is more accurate across
hostnames, environments (localhost vs production), and protocols; path
comparisons now handle exact and prefix matches robustly.
* **Tests**
* Expanded test coverage for domain, locale-path, and custom-path
binding scenarios, including trailing slashes, extra segments, and query
strings.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
What's the purpose of this pull request?
Removing hardcoded labels:
ProductDescriptionaria-label content in hCMS #3142Setting Up locales
custom path
Components
Fetching content
Others
How to test locally?
npmn i/discovery.config.default.js:Enable localization:
node packages/cli/bin/run.js generate-i18n ./packages/coreto fetch the bindingsnpmn dev