npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

vue-router-newtab

v1.0.2

Published

Cmd/Ctrl+click support for newTab router.push() navigation for Vue 3 + Vue Router 4

Downloads

3,655

Readme

New Tab Router

npm version License: MIT TypeScript

A Vue 3 + Vue Router 4 package that adds intelligent navigation behavior, specifically Cmd/Ctrl+click functionality to programmatic router.push() calls.

✨ Features

  • 🎯 Smart Navigation: Automatically detects Cmd/Ctrl key presses during router.push() calls
  • 🆕 New Tab Support: Opens routes in new tabs when modifier keys are pressed
  • 🔧 Highly Configurable: Custom behaviors, callbacks, and route patterns
  • 📱 Cross-Platform: Works on macOS (Cmd), Windows/Linux (Ctrl)
  • 🛡️ Type Safe: Full TypeScript support with comprehensive type definitions
  • 🚀 Zero Breaking Changes: Non-intrusive addition of new tab functionality to existing router
  • 📦 Tree Shakeable: Optimized bundle size with ESM support
  • 🧪 Well Tested: Comprehensive test coverage with Vitest and Playwright

🚀 Quick Start

Installation

npm install vue-router-newtab
# or
yarn add vue-router-newtab
# or
pnpm add vue-router-newtab

Basic Usage

import { createRouter, createWebHistory } from 'vue-router';
import { newTabRouter } from 'vue-router-newtab';

const router = createRouter({
  history: createWebHistory(),
  routes: [
    { path: '/', component: Home },
    { path: '/about', component: About },
    { path: '/contact', component: Contact },
  ],
});

// Enhance the router with Cmd/Ctrl+click support
newTabRouter(router);

// Now your existing router.push() calls work intelligently!
// Cmd/Ctrl + router.push('/about') = opens in new tab
// Normal router.push('/about') = normal navigation

Using with unplugin-vue-router

If you're using unplugin-vue-router for file-based routing, you need to import the type declarations in your main setup file:

// main.ts or router setup file
import 'vue-router-newtab/unplugin-vue-router.d.ts';
import { createApp } from 'vue';
import { createRouter, createWebHistory } from 'vue-router';
import { newTabRouter } from 'vue-router-newtab';

// Your router setup with unplugin-vue-router
const router = createRouter({
  history: createWebHistory(),
  routes: [], // Routes are auto-generated by unplugin-vue-router
});

// Enhance the router with Cmd/Ctrl+click support
newTabRouter(router);

This import ensures that TypeScript recognizes the enhanced router.push() method with the additional options when using unplugin-vue-router's typed routing.

In Your Components

<template>
  <div>
    <button @click="navigateToAbout">About (Cmd/Ctrl+click for new tab)</button>
    <button @click="forceNewTab">Force New Tab</button>
  </div>
</template>

<script setup lang="ts">
import { useRouter } from 'vue-router';

const router = useRouter();

const navigateToAbout = () => {
  // This will open in new tab if Cmd/Ctrl is pressed
  router.push('/about');
};

const forceNewTab = () => {
  // This will always open in new tab
  router.push('/about', { forceNewTab: true });
};

const conditionalNewTab = () => {
  // This will only open in new tab if Cmd/Ctrl is pressed
  router.push('/about', { newTab: true });
};
</script>

📖 API Reference

newTabRouter(router, config?)

Adds new tab functionality to a Vue Router instance with intelligent navigation behavior.

Parameters:

  • router: Router - The Vue Router instance to support newTab behaviour
  • config?: NewTabRouterConfig - Optional configuration object

Returns: NewTabRouter - The router instance with new tab functionality

Configuration Options

interface NewTabRouterConfig {
  /** Enable Cmd/Ctrl+click detection (default: true) */
  enableCtrlClick?: boolean;

  /** Enable debug logging (default: false) */
  debugMode?: boolean;
}

Enhanced Push Options

interface EnhancedPushOptions {
  /** Force opening in new tab regardless of modifier key */
  forceNewTab?: boolean;

  /** Open in new tab only if modifier key is pressed (false prevents new tab behavior) */
  newTab?: boolean;
}

🎛️ Advanced Usage

Debug Mode

newTabRouter(router, {
  debugMode: process.env.NODE_ENV === 'development',
});

Per-Call Customization

// Force new tab for specific calls
router.push('/external-link', { forceNewTab: true });

// Conditional new tab (only if modifier key is pressed)
router.push('/optional-new-tab', { newTab: true });

// Prevent new tab behavior for specific calls
router.push('/normal-navigation', { newTab: false });

🔧 TypeScript Support

The package provides comprehensive TypeScript support with full type definitions:

import type {
  NewTabRouterConfig,
  EnhancedPushOptions,
  NewTabRouter,
} from 'vue-router-newtab';

// Your router is now fully typed
const router: NewTabRouter = newTabRouter(
  createRouter({
    /* ... */
  })
);

// newTab push method with full type safety
router.push('/about', { forceNewTab: true });

🧪 Testing

Unit Tests

npm run test

Coverage

npm run test:coverage

E2E Tests

npm run test:e2e

🌍 Browser Support

  • ✅ Chrome 88+
  • ✅ Firefox 85+
  • ✅ Safari 14+
  • ✅ Edge 88+

📦 Bundle Size

  • ESM: ~3.2KB gzipped
  • CJS: ~3.5KB gzipped

🚨 Important Notes

SSR Compatibility

The new tab router automatically detects server-side environments and skips new tab functionality to prevent SSR errors:

// Safe to use in SSR - will be skipped automatically
newTabRouter(router);

Memory Management

The new tab router automatically cleans up event listeners when the router is destroyed. For manual cleanup:

import { destroyNewTabRouter } from 'vue-router-newtab';

// Clean up when needed
destroyNewTabRouter(router);

Security Considerations

  • New tabs are opened with noopener,noreferrer for security
  • External URLs are detected and handled appropriately
  • Popup blockers are handled gracefully with fallback to normal navigation

🔄 Migration Guide

From Existing Projects

The new tab router is designed to be non-intrusive. Your existing code will work without changes:

// Before
router.push('/about');

// After (same code, enhanced behavior)
newTabRouter(router);
router.push('/about'); // Now supports Cmd/Ctrl+click!

🤝 Contributing

Contributions are welcome! Please read our Contributing Guide for details.

Development Setup

# Clone the repository
git clone https://github.com/sjmc11/vue-router-newtab.git

# Install dependencies
npm install

# Run tests
npm run test

# Build the package
npm run build

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

🙏 Acknowledgments

  • Vue.js team for the amazing framework
  • Vue Router team for the excellent routing solution
  • All contributors who help make this project better

📞 Support


Made with ❤️ for the Vue.js community