Skip to content

feat: expose original style URL via map.getStyleUrl()#7110

Open
giswqs wants to merge 6 commits intomaplibre:mainfrom
giswqs:feature/expose-style-url
Open

feat: expose original style URL via map.getStyleUrl()#7110
giswqs wants to merge 6 commits intomaplibre:mainfrom
giswqs:feature/expose-style-url

Conversation

@giswqs
Copy link
Copy Markdown
Contributor

@giswqs giswqs commented Feb 12, 2026

Summary

  • Add map.getStyleUrl() method that returns the URL used to load the current style
  • Returns null if the style was loaded from a JSON object
  • Preserves URL across style diffing and fallback scenarios

Motivation

Closes #7109

When a map is initialized with a style URL, that URL is not accessible later. The map.getStyle() method returns the current style object which includes all layers - both from the original basemap and any layers added dynamically. There's no way to distinguish between them.

This feature enables plugin developers to:

  • Build layer control plugins that group basemap layers as a single "Basemap" entry
  • Implement style management tools that need to know what basemap is being used
  • Serialize map state with the original style URL separately from dynamic modifications

API

// Get the style URL (returns null if style was provided as object)
const styleUrl = map.getStyleUrl();

// After setStyle() with a URL, it returns the URL
map.setStyle('https://example.com/style.json');
map.getStyleUrl(); // 'https://example.com/style.json'

// If style was set as an object, returns null
map.setStyle({ version: 8, sources: {}, layers: [] });
map.getStyleUrl(); // null

Test plan

  • Added unit tests for Style.getStyleUrl() in style.test.ts
  • Added unit tests for Map.getStyleUrl() in map_style.test.ts
  • All 2710 existing unit tests pass

Add a new `getStyleUrl()` method to the Map class that returns the URL
used to load the current style, or null if the style was loaded from a
JSON object.

This enables plugin developers to:
- Distinguish basemap layers from dynamically added layers
- Build layer control plugins that group basemap layers
- Implement style management tools
- Serialize map state with the original style URL

Closes maplibre#7109
@codecov
Copy link
Copy Markdown

codecov bot commented Feb 12, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 92.68%. Comparing base (ffe3bec) to head (48ac04b).
⚠️ Report is 2 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #7110      +/-   ##
==========================================
+ Coverage   92.66%   92.68%   +0.02%     
==========================================
  Files         289      289              
  Lines       24061    24073      +12     
  Branches     5094     5098       +4     
==========================================
+ Hits        22297    22313      +16     
+ Misses       1764     1760       -4     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Comment thread src/ui/map.ts Outdated
@HarelM
Copy link
Copy Markdown
Collaborator

HarelM commented Feb 13, 2026

Thanks for taking the time to open this PR.
I think that both map and style classes are updating an internal property of the style class, which is not a good pattern.
Please see if you can change that...

- Add setStyleUrl() public method to Style class for URL management
- Add optional sourceUrl parameter to loadJSON() for diff fallback
- Update Map class to use setStyleUrl() instead of direct property access
- Add _updateStyleWithSourceUrl() helper to pass URL through loadJSON

This ensures all _styleUrl property updates happen within the Style
class, addressing code review feedback about encapsulation.
Comment thread src/ui/map.ts Outdated
}
}

private _updateStyleWithSourceUrl(style: StyleSpecification, options?: StyleSwapOptions & StyleOptions, sourceUrl?: string) {
Copy link
Copy Markdown
Collaborator

@HarelM HarelM Feb 18, 2026

Choose a reason for hiding this comment

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

This looks like a bug fix...? Is it related to this PR? I'm not sure I like this waiting approach... Is there an alternative?

Comment thread src/style/style.ts Outdated
*
* @param url - The style URL, or null if the style is not loaded from a URL.
*/
setStyleUrl(url: string | null) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Is it possible not to expose this method and handle updating the style in the relevant place without exposing this?
This API is misleading as it looks like you can set the style URL and have the style updated using this method, but that's not the case...

Comment thread src/ui/map_tests/map_style.test.ts Outdated
});

describe('getStyleUrl', () => {
test('returns null when style is loaded from JSON object', async () => {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

These looks like duplicated tests, I would only keep tests here that are relevant to the changes of the map.ts class as part of this PR.
Seems like setting a styleURL and getting it back is enough as other scenarios are covered by the style.test.ts file (except the added _updateStyleWithSourceUrl logic, which I already reviewed and left my comments on).

- Add sourceUrl parameter to setState() so _styleUrl is updated internally
- Remove public setStyleUrl() method from Style class (was misleading API)
- Remove _updateStyleWithSourceUrl() helper, use _updateStyle with sourceUrl param
- Simplify _diffStyle() by letting setState handle _styleUrl updates
- Reduce duplicate tests in map_style.test.ts as suggested by maintainer
- Add tests for setState with sourceUrl parameter
@giswqs
Copy link
Copy Markdown
Contributor Author

giswqs commented Feb 20, 2026

Thanks for the detailed feedback! I've addressed all the concerns in the latest commit:

  1. Removed setStyleUrl() method - You're right that it was misleading. Now all _styleUrl updates happen internally within Style class methods only.

  2. Removed _updateStyleWithSourceUrl() helper - Simplified by adding an optional sourceUrl parameter to _updateStyle() instead of having a separate method with the "waiting approach".

  3. Added sourceUrl parameter to setState() - When diffing succeeds, _styleUrl is now updated internally within setState() rather than Map reaching into Style's internal state. This keeps all _styleUrl management encapsulated within the Style class.

  4. Reduced duplicate tests - Removed the tests from map_style.test.ts that were duplicating what's already covered in style.test.ts. Kept only the map-specific tests (setting/getting URL through Map interface).

  5. Added tests for setState with sourceUrl - Added proper test coverage in style.test.ts to verify the new parameter works correctly.

All tests pass locally. Let me know if there's anything else that needs adjustment!

Comment thread src/ui/map.ts
}

_updateDiff(style: StyleSpecification, options?: StyleSwapOptions & StyleOptions) {
_updateDiff(style: StyleSpecification, options?: StyleSwapOptions & StyleOptions, sourceUrl?: string) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Would it make sense to add this to the options object?

Comment thread src/ui/map.ts
* ```
*/
getStyleUrl(): string | null {
if (this.style) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Use "?." operator.

@HarelM
Copy link
Copy Markdown
Collaborator

HarelM commented Mar 1, 2026

It is better to answer in the relevant thread and link to the relevant commit, this way I can track which review comment we are talking about...

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.

Feature: Expose the original style URL via map.getStyleUrl()

2 participants