# Chrome 140+ Features (September 2025+) New Chrome Extension APIs introduced in Chrome 140 and later versions. ## Chrome 140 (September 2025) ### sidePanel.getLayout() Determines the position of the side panel (left or right) in the browser window. **Official Documentation:** https://developer.chrome.com/docs/extensions/reference/api/sidePanel#method-getLayout #### API Signature ```typescript chrome.sidePanel.getLayout(): Promise<{ side: 'left' | 'right'; }> ``` #### Basic Usage ```typescript // Get current side panel layout const layout = await chrome.sidePanel.getLayout(); console.log('Side panel is positioned on the:', layout.side); if (layout.side === 'right') { console.log('Side panel is on the right'); } else { console.log('Side panel is on the left'); } ``` #### Use Cases ##### 1. RTL Language Support ```typescript export default defineContentScript({ matches: ['*://*'], async main() { const layout = await chrome.sidePanel.getLayout(); const documentDir = document.documentElement.dir; // Adjust UI based on panel side and text direction if (layout.side === 'right' && documentDir === 'rtl') { // Apply RTL-optimized positioning applyRTLStyles(); } }, }); ``` ##### 2. Dynamic Content Positioning ```typescript // Popup component function App() { const [panelSide, setPanelSide] = useState<'left' | 'right'>('left'); useEffect(() => { chrome.sidePanel.getLayout().then(({ side }) => { setPanelSide(side); }); }, []); return (

Panel is positioned on the {panelSide}

{/* Adjust UI layout based on panel side */}
); } ``` ##### 3. Optimal Notification Placement ```typescript // Background script browser.alarms.onAlarm.addListener(async (alarm) => { const layout = await chrome.sidePanel.getLayout(); // Position notifications away from side panel const notificationPosition = layout.side === 'right' ? 'bottom-left' : 'bottom-right'; await chrome.notifications.create({ type: 'basic', title: 'Reminder', message: 'Task is due', iconUrl: '/icon/128.png', }); }); ``` #### Browser Compatibility - **Chrome:** 140+ (September 2025) - **Firefox:** Not yet supported - **Edge:** 140+ (follows Chromium) - **Safari:** Not applicable (no side panel API) #### Feature Detection Always check if the API is available: ```typescript async function getSidePanelSide(): Promise<'left' | 'right' | null> { if (chrome.sidePanel?.getLayout) { try { const layout = await chrome.sidePanel.getLayout(); return layout.side; } catch (error) { console.error('Failed to get side panel layout:', error); return null; } } return null; // API not available } ``` #### Integration with WXT ```typescript // entrypoints/sidepanel/main.tsx import { useState, useEffect } from 'react'; function SidePanel() { const [side, setSide] = useState<'left' | 'right'>('left'); useEffect(() => { // Get initial side chrome.sidePanel.getLayout().then(({ side }) => { setSide(side); }); // Note: Chrome doesn't fire events when user changes panel side // You may need to periodically check or reload when panel is opened }, []); return (

Side Panel Content

Current side: {side}

); } ``` #### Default Behavior - **New Chrome installations (2025+):** May default to right side - **Upgraded Chrome installations:** Retains user's previous preference - **User can change:** Users can move side panel between left and right at any time #### Common Patterns ##### Responsive Layout Adjustment ```typescript // hooks/useSidePanelPosition.ts import { useState, useEffect } from 'react'; export function useSidePanelSide() { const [side, setSide] = useState<'left' | 'right'>('left'); const [isLoading, setIsLoading] = useState(true); useEffect(() => { if (chrome.sidePanel?.getLayout) { chrome.sidePanel .getLayout() .then(({ side }) => { setSide(side); }) .catch((error) => { console.error('Failed to get side panel side:', error); }) .finally(() => { setIsLoading(false); }); } else { setIsLoading(false); } }, []); return { side, isLoading }; } // Usage in component function MyComponent() { const { side, isLoading } = useSidePanelSide(); if (isLoading) return ; return (
{/* Content positioned based on panel location */}
); } ``` #### Styling Based on Side ```css /* CSS for panel-aware layouts */ .content-left { /* Panel is on left, content flows from right */ margin-left: 20px; margin-right: 0; text-align: left; } .content-right { /* Panel is on right, content flows from left */ margin-left: 0; margin-right: 20px; text-align: right; } /* RTL support */ [dir="rtl"] .content-left { direction: rtl; } ``` ## Staying Updated To stay informed about new Chrome Extension features: 1. **Chrome Extensions What's New:** https://developer.chrome.com/docs/extensions/whats-new 2. **Chrome Developers Blog:** https://developer.chrome.com/blog 3. **Chrome Platform Status:** https://chromestatus.com/features 4. **WXT Changelog:** https://github.com/wxt-dev/wxt/releases ## Migration Guide If your extension currently assumes side panel is always on the left: ### Before (Assumed Left Side) ```typescript // Old code - assumes left side function positionContent() { const content = document.getElementById('content'); content.style.marginLeft = '400px'; // Fixed left margin } ``` ### After (Side-Aware) ```typescript // New code - adapts to panel side async function positionContent() { const content = document.getElementById('content'); if (chrome.sidePanel?.getLayout) { const { side } = await chrome.sidePanel.getLayout(); if (side === 'right') { content.style.marginRight = '400px'; content.style.marginLeft = '0'; } else { content.style.marginLeft = '400px'; content.style.marginRight = '0'; } } } ``` ## Related APIs - **chrome.sidePanel.open()** - Open side panel programmatically - **chrome.sidePanel.close()** - Close side panel - **chrome.sidePanel.setOptions()** - Configure side panel behavior - **chrome.sidePanel.getOptions()** - Get current side panel configuration **Full Side Panel API:** https://developer.chrome.com/docs/extensions/reference/api/sidePanel