Showing both preview and Code Editor in Build Mode

While the UI is now certainly more consistent, I really miss the possibility to show the Code Editor and the App Preview side by side at the same time. (And also hiding the Code assistant) Especially when making multiple quick edits to the code, it is very helpful to be able to check things in the app or see the changes, without having to switch between Code Editor and Preview.

Is there any chance that this feature will return again?

If anyone interested: Fortunately all the elements to make this work are still in place, so it’s also possible to get this feature back with a user script (using an extension like Tampermonkey)

// ==UserScript==
// @name         AI Studio - Custom View & Layout Controls (Advanced)
// @namespace    http://tampermonkey.net/
// @version      2.4
// @description  Adds buttons to toggle views and a stateful menu button to toggle a custom layout with a draggable splitter.
// @author       G
// @match        *://aistudio.google.com/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    const customButtonContainerId = 'custom-view-buttons-container';
    const customSplitterId = 'custom-editor-splitter';
    const customCssId = 'custom-splitter-styles';
    let debounceTimer;

    /**
     * Injects a <style> tag into the document head for the splitter's hover effects.
     * Runs only once.
     */
    const injectCss = () => {
        // If the style tag already exists, do nothing.
        if (document.getElementById(customCssId)) return;

        const style = document.createElement('style');
        style.id = customCssId;
        style.textContent = `
            #${customSplitterId} {
                width: 1px;
                transition: width 0.05s ease-in-out;
            }
            #${customSplitterId}:hover {
                width: 5px;
            }
        `;
        document.head.appendChild(style);
    };

    // --- Helper functions for buttons and dragging (remain the same) ---
    const createToggleButton = (iconName, targetSelector, displayStyle) => {
        const button = document.createElement('button');
        button.className = 'ms-button-icon ms-button-primary';
        button.setAttribute('ms-button', '');
        button.setAttribute('aria-label', `Toggle ${targetSelector}`);
        const iconSpan = document.createElement('span');
        iconSpan.className = 'material-symbols-outlined notranslate ms-button-icon-symbol';
        iconSpan.setAttribute('aria-hidden', 'true');
        iconSpan.textContent = iconName;
        button.appendChild(iconSpan);
        button.addEventListener('click', () => {
            const targetElement = document.querySelector(targetSelector);
            if (targetElement) {
                const currentDisplay = window.getComputedStyle(targetElement).display;
                targetElement.style.display = (currentDisplay === 'none') ? displayStyle : 'none';
            } else {
                console.error(`Could not find element with selector: ${targetSelector}`);
            }
        });
        return button;
    };

    const makeSplitterDraggable = (splitter, targetToResize) => {
        splitter.addEventListener('mousedown', (e) => {
            e.preventDefault();
            const startX = e.clientX;
            const startWidth = parseInt(window.getComputedStyle(targetToResize).flexBasis, 10);
            const handleDrag = (moveEvent) => {
                const deltaX = moveEvent.clientX - startX;
                targetToResize.style.flexBasis = `${startWidth + deltaX}px`;
            };
            const stopDrag = () => {
                document.removeEventListener('mousemove', handleDrag);
                document.removeEventListener('mouseup', stopDrag);
                document.body.style.cursor = '';
            };
            document.addEventListener('mousemove', handleDrag);
            document.addEventListener('mouseup', stopDrag);
            document.body.style.cursor = 'col-resize';
        });
    };

    /**
     * Handles the stateful toggle logic for the 'menu' button click.
     */
    const handleMenuButtonClick = (iconElement) => {
        const rightPanel = document.querySelector('.console-right-panel');
        if (!rightPanel) { console.error("Could not find '.console-right-panel'"); return; }
        const subheader = rightPanel.querySelector('.subheader');
        if (!subheader) { console.error("Could not find '.subheader'"); return; }
        const editorContainer = document.querySelector('.editor-container');
        if (!editorContainer) { console.error("Could not find '.editor-container'"); return; }

        const isLayoutActive = rightPanel.dataset.customLayoutActive === 'true';

        if (isLayoutActive) {
            // --- STATE IS ON: Turn it OFF ---
            subheader.style.cssText = '';
            rightPanel.style.flexFlow = '';
            document.querySelectorAll('.editor-container, .applet-container').forEach(c => c.style.marginTop = '');
            editorContainer.style.flex = '';
            document.getElementById(customSplitterId)?.remove();
            iconElement.style.transform = 'rotate(90deg)';
            delete rightPanel.dataset.customLayoutActive;
        } else {
            // --- STATE IS OFF: Turn it ON ---
            subheader.style.position = 'absolute';
            subheader.style.width = '-webkit-fill-available';
            subheader.style.zIndex = '100';
            rightPanel.style.flexFlow = 'row';
            document.querySelectorAll('.editor-container, .applet-container').forEach(c => c.style.marginTop = '48px');
            editorContainer.style.flex = `0 1 ${editorContainer.offsetWidth}px`;

            const splitter = document.createElement('ms-console-splitter');
            splitter.id = customSplitterId;
            splitter.className = 'visible';
            splitter.style.cursor = 'col-resize';
            // REMOVED: splitter.style.width = '5px'; // This is now handled by the injected CSS
            splitter.style.backgroundColor = 'rgba(128, 128, 128, 0.5)';
            splitter.appendChild(document.createElement('div')).className = 'overlay';
            editorContainer.insertAdjacentElement('afterend', splitter);

            makeSplitterDraggable(splitter, editorContainer);
            iconElement.style.transform = 'rotate(0deg)';
            rightPanel.dataset.customLayoutActive = 'true';
        }
    };

    /**
     * The main function that ensures our custom buttons exist on the page.
     */
    const ensureButtonsExist = () => {
        const targetLocation = document.querySelector('.page-header .left-side');
        if (!targetLocation || document.getElementById(customButtonContainerId)) return;

        const buttonContainer = document.createElement('div');
        buttonContainer.id = customButtonContainerId;
        buttonContainer.style.display = 'flex';
        buttonContainer.style.gap = '8px';
        buttonContainer.style.marginLeft = '16px';

        buttonContainer.appendChild(createToggleButton('code', '.editor-container', 'flex'));
        buttonContainer.appendChild(createToggleButton('devices', '.applet-container', 'flex'));
        buttonContainer.appendChild(createToggleButton('list', '.tree-view-container', 'block'));

        const menuButton = document.createElement('button');
        menuButton.className = 'ms-button-icon ms-button-primary';
        menuButton.setAttribute('ms-button', '');
        menuButton.setAttribute('aria-label', 'Toggle Custom Layout');
        const menuIcon = document.createElement('span');
        menuIcon.className = 'material-symbols-outlined notranslate ms-button-icon-symbol';
        menuIcon.textContent = 'menu';
        menuIcon.style.transform = 'rotate(90deg)';
        menuIcon.style.transition = 'transform 0.2s ease-in-out';
        menuButton.appendChild(menuIcon);
        menuButton.addEventListener('click', () => handleMenuButtonClick(menuIcon));

        buttonContainer.appendChild(menuButton);
        targetLocation.appendChild(buttonContainer);
    };

    // --- SCRIPT INITIALIZATION ---
    injectCss(); // Run the CSS injection once.
    const observer = new MutationObserver(() => {
        clearTimeout(debounceTimer);
        debounceTimer = setTimeout(ensureButtonsExist, 250);
    });
    ensureButtonsExist();
    observer.observe(document.body, { childList: true, subtree: true });

})();

Hello,

Thank you for your valuable feedback, we really appreciate it. We have shared it with the concerned team.