Skip to content

Conversation

@hellofanny
Copy link
Contributor

@hellofanny hellofanny commented Nov 3, 2025

lariciamota and others added 7 commits October 30, 2025 09:26
## What's the purpose of this pull request?

Build our default image loader.

## How it works?

- When the FastStore image component is used, the `faststoreLoader` is
used.
- When the Next image component is used directly, the
`customImageLoader` is used.
- Both have the same behavior when handling images from VTEX (from the
file manager/cms and product images) -- they add to the URL the info
regarding size, quality and aspect, since those VTEX services already
handles optimizations.
- The difference between those loaders is regarding external images --
the one used for Next images uses the Next optimizations, and the
FastStore one doesn't.

It won't be necessary to use a feature flag like
`enableVtexAssetsLoader`.

## How to test it?

<!--- Describe the steps with bullet points. Is there any external link
that can be used to better test it or an example? --->

### Starters Deploy Preview

PR: vtex-sites/faststoreqa.store#881

## References

- [Jira task](https://vtex-dev.atlassian.net/browse/SFS-2878)
- [Slack
thread](https://vtex.slack.com/archives/C03L3CRCDC4/p1761334946034969)
## What's the purpose of this pull request?

Atts.
## What's the purpose of this pull request?

This PR fixes a visual bug in the TextareaField component where long
text would appear underneath the floating label during scroll, making it
difficult to read. The issue was identified during the review of [PR
#2705](#2705 (review)).

Additionally, comprehensive Storybook documentation was added to
showcase all TextareaField variations and use cases.


https://github.com/user-attachments/assets/a86cd4df-e286-40f4-82b0-271a8bc66a26




## How it works?

**Bug Fix:**
- Added `--fs-textarea-field-label-background-color` CSS variable to
`packages/ui/src/components/molecules/TextareaField/styles.scss`
- Set default value to neutral-0 (white) to prevent text from showing
through the label
- When the textarea content is long and the user scrolls, the label now
has an opaque background, preventing text overlap

## How to test it?

**Test the scroll bug fix:**

From the project root:
```bash
pnpm --filter "@faststore/storybook" dev
```

Or navigate to the storybook package:
```bash
cd packages/storybook
pnpm dev
```

Then:
1. Open http://localhost:6006 in your browser
2. Navigate to **"TextareaField"** → **"LargeText"** story
3. Scroll inside the textarea content
4. Verify that the text no longer appears underneath the label

## References
- **Related Issue:** [PR #2705 - TextareaField label overlap issue
identified](#2705 (review))
- **Task:** [SFS-2385 ](https://vtex-dev.atlassian.net/browse/SFS-2385)
## What's the purpose of this pull request?

Revert changes from 
- #2988
since the approach to filter shopper changes to use text field instead
of selected filter in the drawer.

## details

remove purchaseAgentId filter and related components from
`MyAccountListOrders`.

This update removes the purchaseAgentId filter and its associated
components from the MyAccountListOrders section. The changes include:
- Deleting the MyAccountFilterFacetPlacedBy component and its styles.
- Adjusting the MyAccountListOrders and MyAccountSelectedTags components
to eliminate references to purchaseAgentId.
- Cleaning up related styles and imports to streamline the codebase.

These modifications aim to simplify the order filtering process and
improve overall maintainability.
## What's the purpose of this pull request?

From a current Next.js's known issue
([discussion#44013](vercel/next.js#44013)),
these changes aim to add an experimental custom hook to handle scroll
restoration when navigating back from PDPs to PLPs.


https://github.com/user-attachments/assets/9a452081-4c65-4a83-8c16-9775f97d226d

Along with this experimental hook, some adjustments needed to be made to
correct the behavior of related components, such as `Sentinel`.

While the Next.js experimental `scrollRestoration` flag is not working
as it should, we are proposing this FastStore's experimental scroll
restoration alternative.

## How it works?

While navigating through PLPs and loading more pages, when users
navigate to a PDP and navigate back the scroll should be restored to the
last position before the navigation.

### Starters Deploy Preview

vtex-sites/faststoreqa.store#878

## References

#2054
@codesandbox-ci
Copy link

codesandbox-ci bot commented Nov 3, 2025

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.

matheusps and others added 5 commits November 3, 2025 19:06
## What's the purpose of this pull request?

Merge the changes from main
## What's the purpose of this pull request?

By using the direction property users will be able to use RTL or LTR
layouts.
lucasfp13 and others added 4 commits November 6, 2025 16:12
## What's the purpose of this pull request?

With these changes, if merchants remove the footer logo the entire
footer component will not be hid anymore, it will throw a console error
but the component should be displayed with no logo.
#3077)

## What's the purpose of this pull request?

This PR fixes the `border-radius` of the Slider thumb in Firefox. The
current CSS rule for Mozilla uses an inexistent variable, making the
browser render a square instead of a circle:

<img width="1028" height="181" alt="image"
src="https://github.com/user-attachments/assets/50c08d79-a6a9-4d31-b2e7-5ef9e287080f"
/>

## How it works?

The `--fs-slider-thumb-radius` variable is replaced by
`--fs-slider-thumb-border-radius`, the one that is defined in the
default thumb variables.

## How to test it?

- Use the `Local Install Instructions` from the [CodeSandbox
CI](https://ci.codesandbox.io/status/vtex/faststore/pr/3077) to add this
version in the `package.json` of a store.
- Import the `Slider` atom (and styles) in a component following the
docs: https://developers.vtex.com/docs/guides/faststore/atoms-slider
- Run the store in development mode and browse it in Mozilla Firefox.

### Starters Deploy Preview

I'm unable to generate a preview link but here's a screenshot from
localhost:

<img width="1287" height="617" alt="image"
src="https://github.com/user-attachments/assets/f0a5a5e9-d657-41db-9415-303b5d17fefd"
/>

## Checklist

**PR Title and Commit Messages**

- [x] PR title and commit messages follow the [Conventional
Commits](https://www.conventionalcommits.org/en/v1.0.0/) specification
- Available prefixes: `feat`, `fix`, `chore`, `docs`, `style`,
`refactor`, `ci` and `test`

**PR Description**

- [ ] Added a label according to the PR goal - `breaking change`, `bug`,
`contributing`, `performance`, `documentation`..
_(No permissions. It's a bug though.)_

**Dependencies**

- [N/A] Committed the `pnpm-lock.yaml` file when there were changes to
the packages

**Documentation**

- [x] PR description
- [N/A] For documentation changes, ping `@Mariana-Caetano` to review and
update (Or submit a doc request)
@hellofanny hellofanny changed the title chore: changing to acc test feat: multi language Nov 11, 2025
lucasfp13 and others added 11 commits November 11, 2025 18:13
)

## What's the purpose of this pull request?

Adds a new "Pending Approval" filter to the MyAccount orders page,
allowing users to quickly filter orders that require their approval.

## How it works?

- New toggle filter: Added "Pending Approval" as the first filter option
in the orders filter slider
- Toggle switch: Users can turn on/off the filter to show only pending
approval orders
- URL integration: Filter state is reflected in the URL
(?pendingApproval=true)
- Selected tag: When active, shows "Pending my approval" tag below the
search bar

## How to test it?

- Go to /account/orders
- Open filter slider and verify "Pending Approval" is the first option
- Toggle the switch and click "Apply"
- Check URL - should include ?pendingApproval=true
- Verify tag appears - "Pending my approval" tag should show below
search bar
- Test removal - click "×" on tag or "Clear All" to remove filter
- Test direct URL - navigate to /account/orders?pendingApproval=true and
verify filter is active

## Starter deploy preview

vtex-sites/b2bfaststoredev.store#358

## References

[SFS-2618](https://vtex-dev.atlassian.net/browse/SFS-2618)

| List | Filter |
| - | - |
|
![image](https://github.com/user-attachments/assets/70a02298-4461-4b21-926d-8d6b754a78bc)
|
![image](https://github.com/user-attachments/assets/2d6afc76-7153-473a-b839-c141e4f0ca1f)
|

[SFS-2618]:

https://vtex-dev.atlassian.net/browse/SFS-2618?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ

[SFS-2618]:
https://vtex-dev.atlassian.net/browse/SFS-2618?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ

---------

Co-authored-by: Artur Santiago <artur.santiago@cubos.io>
)

## What's the purpose of this pull request?

Fix a bug that occurs when regionalized and `isSessionReady` is sent in
the' validateSession' and' validateCart' mutations.

## How does it work?

It removes the `isSessionReady` from the session sent to the `setRegion`
method.

<img width="1909" height="916" alt="Screenshot 2025-11-11 at 16 22 55"
src="https://github.com/user-attachments/assets/468cc987-a2ee-432f-b306-399bfd32e891"
/>
## What's the purpose of this pull request?

This PR aims to fix the build in the dev branch.
## What's the purpose of this pull request?

With these changes, a loading skeleton will be displayed when product
price is still being validated, preventing product price flickering on
PDP.

## How to test it?

### Starters Deploy Preview
## What's the purpose of this pull request?

Allow svg files in public folder, avoid it getting deleted/overwritten
when generating .faststore

## How it works?

Add it to the allow list.

## How to test it?

Create a svg file or modify an existing svg file, it should be copied
correctly to the `/.faststore/public` when running the build command.
You can use this PR to test:
vtex-sites/faststoreqa.store#887, I've added a
new svg file and changed an existing one, before it was being
deleted/overwritten.
<img width="287" height="420" alt="Screenshot 2025-11-20 at 09 57 19"
src="https://github.com/user-attachments/assets/7b01d806-bdf9-4c3b-a385-32ea11ab2518"
/>

Nothing else should change.

### Starters Deploy Preview

- https://storeframework-cm652ufll028lmgv665a6xv0g-h0max2o2h.b.vtex.app/

## References
- [Jira task](https://vtex-dev.atlassian.net/browse/SO-559)
lariciamota and others added 5 commits November 25, 2025 09:15
## 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)
lemagnetic and others added 8 commits December 1, 2025 18:10
## 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)
@hellofanny hellofanny changed the base branch from main to canary-v2 December 9, 2025 23:27
lariciamota and others added 7 commits December 10, 2025 14:46
## 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>
@coderabbitai
Copy link

coderabbitai bot commented Jan 14, 2026

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.


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

lemagnetic and others added 7 commits January 16, 2026 14:06
## 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 -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants