A modern Vue.js frontend for searching backlinks across 2 billion pages scanned monthly. Built with Vue 3, TypeScript, PrimeVue, and Tailwind CSS.
- Domain Backlink Search: Search backlinks for any domain with real-time results
- Advanced Filtering: Filter by link URL, source host/path, anchor text, nofollow status, and IP
- Export Capabilities: Export results to CSV, Excel, and PDF formats
- Direct Domain URLs: Support for shareable links like
/domain/example.com - Mobile-First Design: Responsive interface optimized for all device sizes
- Real-time Search: Instant results with debounced input and smart filtering
- SEO Optimized: Canonical URLs and proper meta tags for search engines
- Backend API: GlobalLinks backend running on http://localhost:8010
- For Development: Node.js 18+
- For Production: Docker (recommended)
# Install dependencies
npm install
# Start development server
npm run dev
# Open http://localhost:5173/dev/backlink-search in your browser# Copy example environment file
cp .env.example .env.local
# Configure your API endpoint
echo "VITE_APP_API_BASE_URL=http://localhost:8010" > .env.localThe application is available as a Docker container with automatic builds on tags, optimized for production use.
Since this is a private repository, authenticate with GitHub Container Registry:
# Login to GitHub Container Registry
docker login ghcr.io
# Username: your-github-username
# Password: your-github-personal-access-token (with read:packages scope)# Latest stable release
ghcr.io/kris-dev-hub/backlink-search:latest
# Specific versions
ghcr.io/kris-dev-hub/backlink-search:v1.0.0Standalone Frontend:
# Pull and run the frontend
docker pull ghcr.io/kris-dev-hub/backlink-search:latest
docker run -d \
--name backlink-search-frontend \
-p 3000:3000 \
ghcr.io/kris-dev-hub/backlink-search:latestWith Backend Connection:
# Start backend first (adjust as needed for your backend)
docker run -d \
--name backlink-search-backend \
-p 8010:8010 \
your-backend-image:latest
# Start frontend with backend connection
docker run -d \
--name backlink-search-frontend \
-p 3000:3000 \
-e NGINX_BACKEND_URL=http://backlink-search-backend:8010 \
-e BROWSER_BACKEND_URL=http://backlink-search-backend:8010 \
--link backlink-search-backend:backend \
ghcr.io/kris-dev-hub/backlink-search:latestCustom Port:
# Run on different host port
docker run -d \
--name backlink-search-frontend \
-p 8080:3000 \
ghcr.io/kris-dev-hub/backlink-search:latest
# Access at http://localhost:8080Docker Compose (Complete Stack):
version: '3.8'
services:
backend:
image: your-backend-image:latest
ports:
- "8010:8010"
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8010/health"]
interval: 30s
timeout: 10s
retries: 3
frontend:
image: ghcr.io/kris-dev-hub/backlink-search:latest
ports:
- "3000:3000"
environment:
- NGINX_BACKEND_URL=http://backend:8010
- BROWSER_BACKEND_URL=http://backend:8010
depends_on:
- backend
restart: unless-stopped
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3000/"]
interval: 30s
timeout: 5s
retries: 3Runtime Configuration:
NGINX_BACKEND_URL- Backend API URL for nginx proxy (default:http://localhost:8010)- Used for server-side API proxying through nginx
- In Kubernetes, use internal service names (e.g.,
http://backend-service:8010)
BROWSER_BACKEND_URL- Backend API URL for browser (default:http://localhost:8010)- Used for client-side direct API calls
- In Kubernetes, use external/ingress URLs (e.g.,
https://api.example.com)
Docker Examples:
# Local backend (both URLs point to localhost)
docker run -d \
--name backlink-search-frontend \
-p 3000:3000 \
-e NGINX_BACKEND_URL=http://localhost:8010 \
-e BROWSER_BACKEND_URL=http://localhost:8010 \
ghcr.io/kris-dev-hub/backlink-search:latest
# Kubernetes deployment (separate internal/external URLs)
docker run -d \
--name backlink-search-frontend \
-p 3000:3000 \
-e NGINX_BACKEND_URL=http://backend-service:8010 \
-e BROWSER_BACKEND_URL=https://api.example.com \
ghcr.io/kris-dev-hub/backlink-search:latest
# Legacy: BACKEND_URL still supported (sets both NGINX and BROWSER URLs)
docker run -d \
--name backlink-search-frontend \
-p 3000:3000 \
-e BACKEND_URL=http://localhost:8010 \
ghcr.io/kris-dev-hub/backlink-search:latest- Minimal size: ~15-25MB Alpine-based image
- Memory efficient: ~10-20MB RAM usage
- Multi-architecture: Supports AMD64 and ARM64
- Health checks: Built-in health endpoint at
/health - Non-root user: Runs as unprivileged user for security
- Optimized nginx: Gzip compression, caching, security headers
# Build the Docker image locally
docker build -t backlink-search-frontend .
# Run locally built image
docker run -d -p 3000:3000 backlink-search-frontendThe project uses semantic versioning with automatic Docker image builds:
Creating a Release:
# Tag a new version (triggers automated build)
git tag v1.0.0
git push origin v1.0.0
# Images are automatically built and pushed to:
# ghcr.io/kris-dev-hub/backlink-search:v1.0.0
# ghcr.io/kris-dev-hub/backlink-search:latestExample Kubernetes Deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: backlink-search-frontend
spec:
replicas: 2
selector:
matchLabels:
app: backlink-search-frontend
template:
metadata:
labels:
app: backlink-search-frontend
spec:
containers:
- name: frontend
image: ghcr.io/kris-dev-hub/backlink-search:latest
ports:
- containerPort: 3000
env:
- name: NGINX_BACKEND_URL
value: "http://backend-service:8010"
- name: BROWSER_BACKEND_URL
value: "https://api.example.com"
resources:
requests:
memory: "32Mi"
cpu: "10m"
limits:
memory: "64Mi"
cpu: "100m"
---
apiVersion: v1
kind: Service
metadata:
name: backlink-search-frontend-service
spec:
selector:
app: backlink-search-frontend
ports:
- port: 80
targetPort: 3000
type: ClusterIPnpm run dev # Start development server
npm run build # Build for production
npm run preview # Preview production build
npm run lint # Run ESLint
npm run format # Format code with Prettier- Frontend Framework: Vue.js 3 with Composition API
- Language: TypeScript 5.3+
- Build Tool: Vite 5.0+
- UI Components: PrimeVue + Custom HTML tables
- Styling: Tailwind CSS 3.3+
- HTTP Client: Axios
- Export Libraries: XLSX, jsPDF, jsPDF-autoTable
The frontend integrates with the GlobalLinks backend API:
POST /api/links- Search backlinks for a domain with filtering and pagination
{
domain: "example.com",
page: 1,
limit: 25,
sort: "linkUrl",
order: "asc",
filters: [
{ name: "Link Path", val: "blog", kind: "any" },
{ name: "No Follow", val: "1", kind: "exact" }
]
}- Link Path: Filter by link URL patterns
- Source Host: Filter by source domain/host
- Source Path: Filter by source page path
- Anchor: Filter by anchor text
- No Follow: Filter by nofollow status (exact: "1" or "0")
- IP: Filter by server IP address
Support for shareable URLs with automatic search:
/domain/example.com- Direct access to domain search- Automatic canonical URLs pointing to main search page
- SEO-friendly with proper meta tags
- Column-based filters: Filters directly under table headers
- Dual input system: Separate host and path filtering
- Real-time search: 300ms debounced filtering
- Smart pattern matching: Regex support for complex patterns
- CSV Export: Clean CSV with proper escaping
- Excel Export: XLSX format with headers
- PDF Export: Professional landscape layout with optimized columns
- Smart formatting: Full URLs in exports, cleaned data presentation
- Mobile-first: Optimized for mobile devices
- Flexible layout: Adapts to different screen sizes
- Touch-friendly: Proper touch targets and interactions
The project currently has the following known security considerations:
- Issue: SheetJS (xlsx) has prototype pollution and ReDoS vulnerabilities
- Affected: Excel export functionality only
- Mitigation:
- Vulnerability only affects Excel export processing
- Input is controlled (internal backlink data only)
- No user-provided XLSX files are processed
- Consider alternative export libraries if security is critical
- Issue: Development server SSRF vulnerability
- Affected: Development environment only (
npm run dev) - Production Impact: None (Docker builds use production assets)
- Mitigation: Only affects local development server
- β Production builds: Use Docker containers with no development dependencies
- β Input validation: All user inputs are validated before API calls
- β No file uploads: Application doesn't accept user file uploads
- β API proxy: nginx handles all external API communication
β οΈ Excel exports: Only export trusted internal data
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Commit your changes:
git commit -m 'Add amazing feature' - Push to the branch:
git push origin feature/amazing-feature - Open a Pull Request
This project is part of the GlobalLinks/KrisDevHub suite. See the main project for licensing information.
Built with β€οΈ using Vue.js, TypeScript, and modern containerization