How to Override the Default New Tab Page in Chrome Extensions
You can override the default new tab page by declaring a chrome_url_overrides.newtab entry in your extension manifest and pointing it to a custom HTML bundle built with Vite and React.
The jonghakseo/chrome-extension-boilerplate-react-vite repository provides a complete, production-ready implementation of this pattern. By leveraging the chrome_url_overrides API alongside a dedicated Vite build pipeline, you can override the default new tab page with a fully customized React component that compiles to a static bundle Chrome loads instantly.
How the New Tab Override Works
Chrome extensions replace built-in pages through the chrome_url_overrides manifest field. In this boilerplate, the override is wired across three architectural layers: the manifest declaration, the Vite build configuration, and the React source component.
Manifest Declaration
The entry point for the override is defined in chrome-extension/manifest.ts at lines 44–46. This tells Chrome to load your custom page instead of its default new tab interface:
// chrome-extension/manifest.ts (lines 44-46)
chrome_url_overrides: {
newtab: 'new-tab/index.html',
},
Vite Build Pipeline
The custom page is built as a separate Vite entry point located at pages/new-tab/vite.config.mts. This configuration outputs the bundled assets to dist/new-tab/, ensuring the final index.html path matches the manifest declaration exactly:
// pages/new-tab/vite.config.mts
// Configures output to dist/new-tab/index.html
React Component Source
The UI layer lives in pages/new-tab/src/NewTab.tsx. This React component renders the actual content users see when opening a new tab. The module is registered under the package name @extension/new-tab in pages/new-tab/package.json, which the monorepo build system uses to resolve dependencies.
When you run npm run build, Vite compiles pages/new-tab/src/NewTab.tsx into dist/new-tab/index.html. Chrome then serves this file automatically whenever the user opens a new tab, requiring no additional runtime code or background script logic.
Customizing Your New Tab Page
You can modify the override behavior by editing the React component, adding static assets, or adjusting the build configuration.
Edit the React Component
Open pages/new-tab/src/NewTab.tsx to change the layout, styling, or functionality. The component exports a default function that returns JSX, which becomes the root of your new tab page.
Here is a practical example that replaces the default placeholder with a personalized greeting:
// pages/new-tab/src/NewTab.tsx
import React from 'react';
import './NewTab.css'; // Add your own styles here
export default function NewTab() {
const [name, setName] = React.useState('Friend');
return (
<div className="new-tab-root">
<h1>Welcome, {name}!</h1>
<p>This is your custom new tab page.</p>
<input
placeholder="Enter your name"
onChange={e => setName(e.target.value)}
/>
</div>
);
}
Add Static Assets
Place images, fonts, or additional CSS files inside pages/new-tab/public/. Create the folder if it does not exist. Vite automatically copies these files to dist/new-tab/ during the build, allowing you to reference them with relative paths in your code.
Build and Reload
After making changes, rebuild the extension to regenerate the dist/new-tab/ bundle:
npm run build
Or use pnpm build if you are using pnpm. Once the build completes, navigate to chrome://extensions, click Reload on your development extension, and open a new tab to see your custom UI.
Summary
- Manifest configuration: The override is declared in
chrome-extension/manifest.tsusingchrome_url_overrides.newtabpointing tonew-tab/index.html. - Build pipeline:
pages/new-tab/vite.config.mtscompiles the React source intodist/new-tab/index.html, matching the manifest path. - Source location: The React component lives at
pages/new-tab/src/NewTab.tsxand is registered under@extension/new-tab. - Customization: Edit the React component, place assets in
pages/new-tab/public/, rebuild withnpm run build, and reload the extension to apply changes.
Frequently Asked Questions
Which manifest field declares the new tab override?
The chrome_url_overrides.newtab field in chrome-extension/manifest.ts (lines 44–46) tells Chrome to load your custom page instead of the default new tab interface. It must point to the relative path new-tab/index.html, which maps to the Vite output directory.
Can I use vanilla JavaScript instead of React for the new tab page?
The boilerplate is configured for React in pages/new-tab/src/NewTab.tsx and pages/new-tab/vite.config.mts. While you could theoretically modify the Vite configuration to use a vanilla JavaScript entry point, the repository is designed around React components for consistency with the rest of the monorepo architecture.
Where should I place images and fonts for the new tab page?
Place static assets inside pages/new-tab/public/. Vite automatically copies files from this directory to dist/new-tab/ during the build process, allowing you to reference them with relative URLs in your React components or CSS files.
Why is my custom new tab page not appearing after building?
Ensure you have reloaded the extension from chrome://extensions after running npm run build. Chrome caches extension resources aggressively, and the manifest changes in chrome-extension/manifest.ts only take effect after a full reload. Also verify that dist/new-tab/index.html exists and matches the path declared in the manifest.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →