vue-router-newtab

Cmd/Ctrl+click support for newTab router.push() navigation for Vue 3 + Vue Router 4
17,540
Install
npm install vue-router-newtab
Latest Version:1.0.2
Vue:3
License:MIT
Last Updated:Sep 15, 2025
Links: npm
Maintainer: sjmc11

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

Related Packages

vue-router-ns

Vue Router's API for NativeScript-Vue, built on top of the native navigation sta...

0 11
@composy/router-vue

Vue 3 router library with enhanced features, built on vue-router

0
vue-navigation

A page navigation library, built with vue2 and vue-router2.

6,916 1,017
vue-router-tiny

A router for Vue.js

654 3
vue-router-sitemap

Module to generate a sitemap for vue-router configuration

3,327 111

Version History

Version Released Vue License
1.0.2 ^3.0.0 MIT
1.0.1 ^3.0.0 MIT
1.0.0 ^3.0.0 MIT