Получение ссылки на фрагмент карты

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
        <script crossorigin src="https://cdn.jsdelivr.net/npm/@babel/standalone@7/babel.min.js"></script>
        <script crossorigin src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>
        <!-- To make the map appear, you must add your apikey -->
        <script src="https://api-maps.yandex.ru/v3/?apikey=<YOUR_APIKEY>&lang=en_US" type="text/javascript"></script>

        <script
            data-plugins="transform-modules-umd"
            data-presets="typescript"
            type="text/babel"
            src="../variables.ts"
        ></script>
        <script
            data-plugins="transform-modules-umd"
            data-presets="typescript"
            type="text/babel"
            src="./common.ts"
        ></script>
        <script data-plugins="transform-modules-umd" data-presets="typescript" type="text/babel">
            import type {
                BehaviorMapEventHandler,
                LngLat,
                YMapCenterLocation,
                YMapLocationRequest,
                YMapZoomLocation
            } from '@yandex/ymaps3-types';
            import {getQueryParams, updateQueryParams} from './common';
            import {LOCATION} from '../variables';
            
            window.map = null;
            
            main();
            
            async function main() {
                // Waiting for all api elements to be loaded
                await ymaps3.ready;
                const {YMap, YMapDefaultSchemeLayer, YMapListener} = ymaps3;
            
                let mapLocation: YMapLocationRequest = LOCATION;
            
                const currentCenter = getQueryParams('spn');
                const currentZoom = getQueryParams('z');
            
                if (currentCenter) {
                    (mapLocation as YMapCenterLocation).center = currentCenter.split(',').map(parseFloat) as LngLat;
                }
            
                if (currentZoom) {
                    (mapLocation as YMapZoomLocation).zoom = parseFloat(currentZoom);
                }
            
                // Initialize the map
                map = new YMap(
                    // Pass the link to the HTMLElement of the container
                    document.getElementById('app'),
                    // Pass the map initialization parameters
                    {location: mapLocation, showScaleInCopyrights: true},
                    // Add a map scheme layer
                    [new YMapDefaultSchemeLayer({})]
                );
            
                // Handler function for changing the status of the onActionEnd event
                const updateHandler: BehaviorMapEventHandler = _.debounce((object) => {
                    updateQueryParams('spn', object.location.center.map((langLat) => langLat.toFixed(6)).join(','));
                    updateQueryParams('z', object.location.zoom.toString());
                }, 250);
            
                /* Add a listener to the map and pass the handlers functions for the events you want to process
              These are just some of the events, you can see them all in the documentation */
                map.addChild(
                    new YMapListener({
                        onActionEnd: updateHandler
                    })
                );
            }
        </script>

        <style> html, body, #app { width: 100%; height: 100%; margin: 0; padding: 0; font-family: Arial, Helvetica, sans-serif; } .toolbar { position: absolute; z-index: 1000; top: 0; left: 0; display: flex; align-items: center; padding: 16px; } .toolbar a { padding: 16px; }  </style>
        <link rel="stylesheet" href="./common.css" />
        <link rel="stylesheet" href="../variables.css" />
    </head>
    <body>
        <div id="app"></div>
    </body>
</html>
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
        <script crossorigin src="https://cdn.jsdelivr.net/npm/react@17/umd/react.production.min.js"></script>
        <script crossorigin src="https://cdn.jsdelivr.net/npm/react-dom@17/umd/react-dom.production.min.js"></script>
        <script crossorigin src="https://cdn.jsdelivr.net/npm/@babel/standalone@7/babel.min.js"></script>
        <script crossorigin src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>
        <!-- To make the map appear, you must add your apikey -->
        <script src="https://api-maps.yandex.ru/v3/?apikey=<YOUR_APIKEY>&lang=en_US" type="text/javascript"></script>

        <script
            data-plugins="transform-modules-umd"
            data-presets="typescript"
            type="text/babel"
            src="../variables.ts"
        ></script>
        <script
            data-plugins="transform-modules-umd"
            data-presets="typescript"
            type="text/babel"
            src="./common.ts"
        ></script>
        <script data-plugins="transform-modules-umd" data-presets="react, typescript" type="text/babel">
            import type {BehaviorMapEventHandler, LngLat, YMapLocationRequest} from '@yandex/ymaps3-types';
            import {getQueryParams, updateQueryParams} from './common';
            import {LOCATION} from '../variables';
            
            window.map = null;
            
            main();
            
            async function main() {
                const [ymaps3React] = await Promise.all([ymaps3.import('@yandex/ymaps3-reactify'), ymaps3.ready]);
                const reactify = ymaps3React.reactify.bindTo(React, ReactDOM);
                const {YMap, YMapDefaultSchemeLayer, YMapDefaultFeaturesLayer, YMapListener} = reactify.module(ymaps3);
                const {useState, useMemo, useEffect} = React;
            
                function App() {
                    const [mapLocation, setMapLocation] = useState<YMapLocationRequest>(LOCATION);
            
                    // Handler function for changing the status of the onUpdate event
                    const updateHandler: BehaviorMapEventHandler = useMemo(() => {
                        return _.debounce((object) => {
                            updateQueryParams('spn', object.location.center.map((latLang) => latLang.toFixed(6)).join(','));
                            updateQueryParams('z', object.location.zoom.toString());
                        }, 250);
                    }, []);
            
                    useEffect(() => {
                        const currentCenter = getQueryParams('spn');
                        const currentZoom = getQueryParams('z');
                        if (currentCenter) {
                            setMapLocation((state) => ({
                                ...state,
                                center: currentCenter.split(',').map(parseFloat) as unknown as LngLat
                            }));
                        }
                        if (currentZoom) {
                            setMapLocation((state) => ({
                                ...state,
                                zoom: parseFloat(currentZoom)
                            }));
                        }
                    }, []);
            
                    return (
                        <YMap location={mapLocation} showScaleInCopyrights={true} ref={(x) => (map = x)}>
                            <YMapDefaultSchemeLayer />
            
                            <YMapDefaultFeaturesLayer />
            
                            {/* Add a listener to the map and pass the handlers functions for the events you want to process
                            These are just some of the events, you can see them all in the documentation */}
                            <YMapListener onActionEnd={updateHandler} />
                        </YMap>
                    );
                }
            
                ReactDOM.render(
                    <React.StrictMode>
                        <App />
                    </React.StrictMode>,
                    document.getElementById('app')
                );
            }
        </script>

        <style> html, body, #app { width: 100%; height: 100%; margin: 0; padding: 0; font-family: Arial, Helvetica, sans-serif; } .toolbar { position: absolute; z-index: 1000; top: 0; left: 0; display: flex; align-items: center; padding: 16px; } .toolbar a { padding: 16px; }  </style>
        <link rel="stylesheet" href="./common.css" />
        <link rel="stylesheet" href="../variables.css" />
    </head>
    <body>
        <div id="app"></div>
    </body>
</html>
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
        <script crossorigin src="https://cdn.jsdelivr.net/npm/vue@3/dist/vue.global.js"></script>
        <script crossorigin src="https://cdn.jsdelivr.net/npm/@babel/standalone@7/babel.min.js"></script>
        <script crossorigin src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>
        <!-- To make the map appear, you must add your apikey -->
        <script src="https://api-maps.yandex.ru/v3/?apikey=<YOUR_APIKEY>&lang=en_US" type="text/javascript"></script>

        <script
            data-plugins="transform-modules-umd"
            data-presets="typescript"
            type="text/babel"
            src="../variables.ts"
        ></script>
        <script
            data-plugins="transform-modules-umd"
            data-presets="typescript"
            type="text/babel"
            src="./common.ts"
        ></script>
        <script data-plugins="transform-modules-umd" data-presets="typescript" type="text/babel">
            import type {LngLat, YMapCenterLocation, YMapLocationRequest, YMapZoomLocation} from '@yandex/ymaps3-types';
            import {getQueryParams, updateQueryParams} from './common';
            import {LOCATION} from '../variables';
            
            window.map = null;
            
            async function main() {
                // For each object in the JS API, there is a Vue counterpart
                // To use the Vue version of the API, include the module @yandex/ymaps3-vuefy
                const [ymaps3Vue] = await Promise.all([ymaps3.import('@yandex/ymaps3-vuefy'), ymaps3.ready]);
                const vuefy = ymaps3Vue.vuefy.bindTo(Vue);
                const {YMap, YMapDefaultSchemeLayer, YMapListener} = vuefy.module(ymaps3);
            
                const app = Vue.createApp({
                    components: {
                        YMap,
                        YMapDefaultSchemeLayer,
                        YMapListener
                    },
                    setup() {
                        const refMap = (ref) => {
                            window.map = ref?.entity;
                        };
                        const mapLocation = Vue.ref<YMapLocationRequest>(LOCATION);
            
                        const currentCenter = getQueryParams('spn');
                        const currentZoom = getQueryParams('z');
            
                        if (currentCenter) {
                            (mapLocation.value as YMapCenterLocation).center = currentCenter.split(',').map(parseFloat) as LngLat;
                        }
            
                        if (currentZoom) {
                            (mapLocation.value as YMapZoomLocation).zoom = parseFloat(currentZoom);
                        }
            
                        const updateHandler = _.debounce((object) => {
                            updateQueryParams('spn', object.location.center.map((langLat) => langLat.toFixed(6)).join(','));
                            updateQueryParams('z', object.location.zoom.toString());
                        }, 250);
            
                        return {
                            mapLocation,
                            updateHandler,
                            LOCATION,
                            updateQueryParams,
                            getQueryParams,
                            refMap
                        };
                    },
            
                    template: `
                  <!-- Initialize the map and pass initialization parameters -->
                  <YMap :location="mapLocation" :showScaleInCopyrights="true" :ref="refMap">
                    <!-- Add a map scheme layer -->
                    <YMapDefaultSchemeLayer/>
            
                    <!-- Add a listener to the map and pass the handlers functions for the events you want to process
                    These are just some of the events, you can see them all in the documentation -->
                    <YMapListener
                      :onActionEnd="updateHandler"
                    />
                  </YMap>
                `
                });
                app.mount('#app');
            }
            
            main();
        </script>

        <style> html, body, #app { width: 100%; height: 100%; margin: 0; padding: 0; font-family: Arial, Helvetica, sans-serif; } .toolbar { position: absolute; z-index: 1000; top: 0; left: 0; display: flex; align-items: center; padding: 16px; } .toolbar a { padding: 16px; }  </style>
        <link rel="stylesheet" href="./common.css" />
        <link rel="stylesheet" href="../variables.css" />
    </head>
    <body>
        <div id="app"></div>
    </body>
</html>
import type {YMapLocationRequest} from '@yandex/ymaps3-types';

export const LOCATION: YMapLocationRequest = {
    center: [37.623082, 55.75254], // starting position [lng, lat]
    zoom: 11 // starting zoom
};
export const updateQueryParams = (key: string, value: string) => {
    const url = new URL(window.location as unknown as string);
    url.searchParams.set(key, value);
    window.history.replaceState({}, '', url);
};

export const getQueryParams = (key: string) => {
    const url = new URL(window.location as unknown as string);
    return url.searchParams.get(key);
};