Files
2025-11-30 09:01:07 +08:00

6.6 KiB

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

chrome.sidePanel.getLayout(): Promise<{
  side: 'left' | 'right';
}>

Basic Usage

// 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
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
// Popup component
function App() {
  const [panelSide, setPanelSide] = useState<'left' | 'right'>('left');

  useEffect(() => {
    chrome.sidePanel.getLayout().then(({ side }) => {
      setPanelSide(side);
    });
  }, []);

  return (
    <div className={`panel-${panelSide}`}>
      <p>Panel is positioned on the {panelSide}</p>
      {/* Adjust UI layout based on panel side */}
    </div>
  );
}
3. Optimal Notification Placement
// 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:

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

// 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 (
    <div className={`sidepanel-container side-${side}`}>
      <header className={side === 'right' ? 'rtl' : 'ltr'}>
        <h1>Side Panel Content</h1>
      </header>
      <main>
        <p>Current side: {side}</p>
      </main>
    </div>
  );
}

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
// 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 <LoadingSpinner />;

  return (
    <div className={`content-${side}`}>
      {/* Content positioned based on panel location */}
    </div>
  );
}

Styling Based on Side

/* 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)

// Old code - assumes left side
function positionContent() {
  const content = document.getElementById('content');
  content.style.marginLeft = '400px'; // Fixed left margin
}

After (Side-Aware)

// 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';
    }
  }
}
  • 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