Setting Up CloudFront Functions for Hugo Page Routing
Setting Up CloudFront Functions for Hugo Page Routing
When hosting a Hugo site on AWS CloudFront, URLs ending with a trailing slash (like /about/) don’t automatically resolve to their corresponding index.html files. While Lambda@Edge can solve this, CloudFront Functions provide a more cost-effective and faster solution. This article will guide you through setting up a CloudFront Function to handle this routing properly.
Why CloudFront Functions?
CloudFront Functions are a perfect fit for this URL rewriting task because:
- Cost: Up to 1/6th the cost of Lambda@Edge
- Performance: Sub-millisecond execution times
- Simplicity: Easier to deploy and manage
- Scale: Automatic scaling at CloudFront’s edge locations
Creating the CloudFront Function
First, let’s create the function that will handle the URL rewriting:
- Go to the CloudFront console
- Navigate to “Functions” in the left sidebar
- Click “Create function”
- Name your function (e.g.,
hugo-page-routing) - Use the following code:
function handler(event) {
var request = event.request;
var uri = request.uri;
// If URI ends with a trailing slash, append 'index.html'
if (uri.endsWith('/')) {
request.uri = uri + 'index.html';
}
// If URI doesn't have an extension, append '/index.html'
else if (!uri.includes('.')) {
request.uri = uri + '/index.html';
}
return request;
}
Testing the Function
CloudFront provides a built-in testing environment:
- Click the “Test” tab
- Create test events for different scenarios:
{ "request": { "uri": "/about/", "method": "GET" } } - Test cases should include:
/about/→/about/index.html/about→/about/index.html/styles.css→/styles.css(unchanged)/posts/my-post/→/posts/my-post/index.html
Associating with Your Distribution
After testing, associate the function with your CloudFront distribution:
- Go to your CloudFront distribution
- Select the “Behaviors” tab
- Edit the default behavior
- Under “Function associations”:
- Event Type: Viewer Request
- Function: Select your function
- Save changes
The deployment is immediate - no waiting for propagation like with Lambda@Edge!
Function Limitations
Be aware of CloudFront Functions limitations:
- Maximum execution time: 1ms
- No external network calls
- No file system access
- Limited JavaScript runtime features
- Maximum function size: 10KB
For this URL rewriting task, these limitations don’t affect us.
Monitoring and Logs
Monitor your function’s performance:
- CloudFront console provides:
- Invocation metrics
- Error rates
- Execution time statistics
- CloudWatch metrics show:
- Function invocations
- Error count
- Latency percentiles
Common Issues and Solutions
Cache Behavior Settings
Ensure your CloudFront cache behavior is configured correctly:
- Forward query strings if needed by Hugo
- Set appropriate TTLs
- Configure correct origin response timeout
403/404 Errors
If you encounter these errors:
- Check S3 bucket permissions
- Verify CloudFront origin path
- Test function behavior with sample requests
- Validate URI rewriting logic
Function Execution Errors
If the function fails:
- Check syntax errors
- Verify URI manipulation logic
- Test with various input patterns
- Review CloudFront metrics
Best Practices
-
Testing:
- Test all URL patterns
- Verify function behavior with query strings
- Check handling of special characters
-
Maintenance:
- Keep function code simple
- Document URL transformation rules
- Monitor performance metrics
-
Security:
- Don’t include sensitive information
- Validate input URIs
- Consider adding security headers
-
Development:
- Use version control for function code
- Maintain test cases
- Document deployment process
Cost Considerations
CloudFront Functions are extremely cost-effective:
- First 2 million requests per month are free
- $0.10 per million requests after free tier
- No charges for function duration
- No regional data transfer fees
Compare this to Lambda@Edge:
- Higher per-request cost
- Charged for function duration
- Regional data transfer fees apply
Conclusion
Using CloudFront Functions for Hugo page routing provides a fast, cost-effective solution for handling URL rewrites. The simple implementation, immediate deployment, and minimal maintenance make it the ideal choice over Lambda@Edge for this specific use case.
Remember to:
- Test thoroughly before deployment
- Monitor performance metrics
- Keep the function code simple and focused
- Document any custom routing rules