start . me .
Directory path . web , gh , editor .

HTML Document File : ht-persist.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ht-persist Example</title>
    <style>
        html,
        body {
            margin: 0;
            padding: 0;
            height: 100%;
            overflow: hidden;
        }

        iframe {
            border: 0;
            width: 100%;
            height: 100%;
        }
    </style>
</head>

<body>
    <iframe src="about:blank"></iframe>
    <script>
        window.persistentData = {}; // Shared data object

        const iframe = document.querySelector('iframe');

        function updateParent() {
            if (iframe.contentWindow.location.href === 'about:blank') {
                return;
            }
            // Update title
            parent.document.title = iframe.contentWindow.document.title;

            // Update URL hash with relative path
            const iframeFullPath = iframe.contentWindow.location.pathname + iframe.contentWindow.location.search;
            const parentDir = window.location.pathname.substring(0, window.location.pathname.lastIndexOf('/'));
            let relativePath = iframeFullPath;
            if (relativePath.startsWith(parentDir)) {
                relativePath = relativePath.substring(parentDir.length);
            }
            if (relativePath.startsWith('/')) {
                relativePath = relativePath.substring(1);
            }

            const newHash = relativePath;
            if (newHash && '#' + newHash !== window.location.hash) {
                history.pushState({ path: newHash }, '', '#' + newHash);
            }
        }

        function updateIframe() {
            const newSrc = window.location.hash.substring(1);
            if (newSrc) {
                if (iframe.src.endsWith('about:blank')) {
                    iframe.src = newSrc;
                    return;
                }

                // Get current iframe relative path to avoid loops
                const iframeFullPath = iframe.contentWindow.location.pathname + iframe.contentWindow.location.search;
                const parentDir = window.location.pathname.substring(0, window.location.pathname.lastIndexOf('/'));
                let currentRelativePath = iframeFullPath;
                if (currentRelativePath.startsWith(parentDir)) {
                    currentRelativePath = currentRelativePath.substring(parentDir.length);
                }
                if (currentRelativePath.startsWith('/')) {
                    currentRelativePath = currentRelativePath.substring(1);
                }

                if (newSrc !== currentRelativePath) {
                    iframe.src = newSrc;
                }
            }
        }

        iframe.onload = function () {
            updateParent();

            if (iframe.contentWindow.location.href === 'about:blank') {
                return;
            }
            const iframeDoc = iframe.contentWindow.document;
            // Use event delegation to handle clicks on links
            iframeDoc.addEventListener('click', function (event) {
                const link = event.target.closest('a');
                if (link && link.href) {
                    // Check if the link is external by comparing hostnames
                    const linkUrl = new URL(link.href, iframe.contentWindow.location.href);
                    if (linkUrl.hostname !== window.location.hostname) {
                        event.preventDefault();
                        window.open(link.href, '_blank');
                    }
                }
            });
        };

        window.addEventListener('hashchange', updateIframe);

        // Initial load
        if (window.location.hash) {
            updateIframe();
        } else {
            const initialSrc = 'editor.html';
            history.replaceState({ path: initialSrc }, '', '#' + initialSrc);
            iframe.src = initialSrc;
        }
    </script>
</body>

</html>