Step Redirect Controller
Path: internal/api/v1/funnels/controllers/step.redirect.controller.js
Service: stepRedirectService
Module: Funnels
Overview
The Step Redirect controller handles URL redirects for funnel steps. It enables redirect-type steps that automatically forward visitors to external URLs or other funnel steps.
Key Capabilities
- Dynamic Redirects: 301 permanent redirects to configured URLs
- Internal Redirects: Redirect between funnel steps
- External Redirects: Redirect to external websites
- Query Parameter Preservation: Maintains UTM and tracking parameters
Methods
redirectStep()
Performs a 301 redirect to the configured destination for a step.
Route: GET /v1/funnels/redirect
Auth: Optional (public endpoint)
Request Query Parameters
{
step_id: string; // Step ID to redirect from
funnel_id: string; // Funnel ID
base_path: string; // Funnel base path
}
Response
- HTTP Status:
301 Moved Permanently - Location Header: Redirect destination URL
Example Request
GET /v1/funnels/redirect?step_id=60d5ec49f1b2c72e8c8e4b1d&funnel_id=60d5ec49f1b2c72e8c8e4b1a&base_path=/landing
Example Response (Internal Redirect)
HTTP/1.1 301 Moved Permanently
Location: https://example.com/landing/thank-you?utm_source=google&utm_medium=cpc
Example Response (External Redirect)
HTTP/1.1 301 Moved Permanently
Location: https://external-website.com/offer?utm_source=google&utm_medium=cpc
MongoDB Collections
| Collection | Operation | Purpose |
|---|---|---|
funnel_steps | findOne | Retrieve step redirect configuration |
funnels | findOne | Get funnel domain info |
Data Models
Step Redirect Configuration
{
_id: ObjectId;
funnel_id: ObjectId;
name: string;
path: string;
type: 'redirect'; // Step type must be "redirect"
order: number;
// Redirect configuration
redirect: {
type: 'internal' | 'external';
// For internal redirects
target_step_id?: ObjectId;
// For external redirects
target_url?: string;
// Options
preserve_query_params: boolean; // Maintain UTM params, etc.
status_code?: 301 | 302; // Default: 301 (permanent)
};
created_at: Date;
updated_at: Date;
}
Business Logic & Workflows
Redirect Resolution Flow
sequenceDiagram
participant Visitor
participant Redirect
participant Database
participant Target
Visitor->>Redirect: GET /redirect?step_id&funnel_id
Redirect->>Database: Find step redirect config
Database-->>Redirect: Step with redirect settings
alt Internal Redirect
Redirect->>Database: Find target step
Database-->>Redirect: Target step URL
Redirect->>Redirect: Build internal URL
else External Redirect
Redirect->>Redirect: Use configured URL
end
alt Preserve Query Params
Redirect->>Redirect: Append original query string
end
Redirect-->>Visitor: 301 Redirect (Location header)
Visitor->>Target: Follow redirect
Redirect Types
Internal Redirect (Step to Step)
Configuration:
{
"type": "redirect",
"redirect": {
"type": "internal",
"target_step_id": "60d5ec49f1b2c72e8c8e4b1e",
"preserve_query_params": true
}
}
Example:
- Original URL:
https://example.com/landing/redirect?utm_source=google - Redirect to:
https://example.com/landing/thank-you?utm_source=google
External Redirect
Configuration:
{
"type": "redirect",
"redirect": {
"type": "external",
"target_url": "https://external-site.com/offer",
"preserve_query_params": true
}
}
Example:
- Original URL:
https://example.com/landing/redirect?utm_source=google - Redirect to:
https://external-site.com/offer?utm_source=google
Use Cases
1. Thank You Page Redirects
Redirect after form submission to thank you page:
{
"name": "Form Submit Redirect",
"path": "/form-submitted",
"type": "redirect",
"redirect": {
"type": "internal",
"target_step_id": "thank_you_step_id"
}
}
2. External Offer Redirects
Redirect to partner/affiliate site:
{
"name": "Partner Offer",
"path": "/partner-offer",
"type": "redirect",
"redirect": {
"type": "external",
"target_url": "https://partner.com/offer?ref=account123",
"preserve_query_params": true
}
}
3. Mobile Redirects
Redirect mobile users to app store:
{
"name": "Mobile App Redirect",
"path": "/mobile",
"type": "redirect",
"redirect": {
"type": "external",
"target_url": "https://apps.apple.com/app/myapp",
"preserve_query_params": false
}
}
Performance Considerations
Caching
- Step redirect config cached for 5 minutes
- Cache key:
redirect:${step_id} - Invalidated on step update
Query Optimization
- Indexed fields:
step_id,funnel_id,type - Single database query per redirect
- No external API calls
Security
Redirect Validation
- Target URLs validated (no javascript: or data: URLs)
- Internal redirects verified within same funnel
- HTTPS enforced for external redirects
Open Redirect Prevention
- Whitelist of allowed external domains (optional)
- Validate target_url format
- Log all external redirects for monitoring
Error Handling
Common Errors
// Step not found
{
"success": false,
"message": "Step not found",
"statusCode": 404
}
// Invalid step type
{
"success": false,
"message": "Step is not a redirect type",
"statusCode": 400
}
// Missing redirect configuration
{
"success": false,
"message": "Redirect configuration not found",
"statusCode": 500
}
// Invalid target URL
{
"success": false,
"message": "Invalid redirect target URL",
"statusCode": 400
}
Best Practices
When to Use This Controller
- ✅ Post-form submission redirects
- ✅ A/B testing with redirect splits
- ✅ Affiliate link redirects
- ✅ Mobile/desktop redirect splits
- ✅ Temporary campaign redirects
Common Patterns
- Always preserve UTMs: Enable
preserve_query_paramsfor tracking - Use 301 for permanent: Use 301 for SEO-friendly permanent redirects
- Use 302 for temporary: Use 302 for A/B tests or temporary campaigns
- Validate external URLs: Ensure HTTPS and valid domain
Edge Cases
- Circular redirects: Prevent step redirecting to itself
- Chain redirects: Limit redirect chain to prevent loops
- Query param conflicts: Handle duplicate parameters gracefully
- Fragment identifiers: Preserve URL fragments (#anchor)
Related Documentation
- Funnels Controller: Step creation and configuration
- Analytics Controller: Track redirect conversion rates
- Forms Controller: Post-submission redirect workflows
Last Updated: January 2025
API Version: v1
Maintained By: DashClicks Engineering