Skip to content

Commit a111f61

Browse files
authored
fix: resolver problema de URLs sin extensión .html en producción (#44)
* fix(config): agregar use_directory_urls para manejar URLs sin extensión - Configurar use_directory_urls: true en mkdocs.yml - Permite que URLs como /meetups/ funcionen correctamente - Mantiene compatibilidad con estructura de directorios de MkDocs * feat(infra): implementar CloudFront Function para URLs sin extensión - Agregar CloudFront Function url_rewrite para manejar URLs sin .html - Función redirige /meetups/ a /meetups/index.html automáticamente - Asociar función con todos los cache behaviors para consistencia - Soluciona problema de enlaces que no funcionan en producción * docs: agregar documentación para fix de URLs sin extensión - Documentar problema de URLs que no funcionan en producción - Explicar solución implementada con CloudFront Function - Incluir pasos de despliegue y verificación - Agregar notas técnicas sobre funcionamiento de la solución
1 parent 74b854d commit a111f61

File tree

3 files changed

+137
-0
lines changed

3 files changed

+137
-0
lines changed

docs/URL_FIX_DOCUMENTATION.md

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# Fix para URLs sin extensión .html en producción
2+
3+
## Problema
4+
Los enlaces funcionaban correctamente en local pero no en producción. Por ejemplo:
5+
-`https://pythoncdmx.org/meetups/` no funcionaba
6+
-`https://pythoncdmx.org/meetups/index.html` sí funcionaba
7+
8+
## Causa
9+
El problema se debía a que CloudFront no estaba configurado para manejar URLs sin extensión `.html`. Cuando MkDocs genera el sitio con `use_directory_urls: true`, crea URLs como `/meetups/` que apuntan a `/meetups/index.html`, pero CloudFront no sabía cómo resolver estas URLs.
10+
11+
## Solución Implementada
12+
13+
### 1. Configuración en mkdocs.yml
14+
```yaml
15+
# URL configuration
16+
use_directory_urls: true
17+
```
18+
19+
### 2. CloudFront Function
20+
Se agregó una función CloudFront que maneja automáticamente las URLs sin extensión:
21+
22+
```javascript
23+
function handler(event) {
24+
var request = event.request;
25+
var uri = request.uri;
26+
27+
// If the URI ends with a slash, try to serve index.html
28+
if (uri.endsWith('/')) {
29+
request.uri = uri + 'index.html';
30+
}
31+
// If the URI doesn't have an extension, try to add .html
32+
else if (!uri.includes('.') && !uri.endsWith('/')) {
33+
request.uri = uri + '.html';
34+
}
35+
36+
return request;
37+
}
38+
```
39+
40+
### 3. Asociación con Cache Behaviors
41+
La función se asoció con todos los cache behaviors de CloudFront para asegurar consistencia.
42+
43+
## Archivos Modificados
44+
45+
1. **mkdocs.yml**: Agregada configuración `use_directory_urls: true`
46+
2. **terraform/cloudfront.tf**:
47+
- Agregada CloudFront Function `url_rewrite`
48+
- Asociada la función con todos los cache behaviors
49+
50+
## Despliegue
51+
52+
Para aplicar estos cambios:
53+
54+
1. **Aplicar cambios de Terraform**:
55+
```bash
56+
cd terraform
57+
terraform plan
58+
terraform apply
59+
```
60+
61+
2. **Desplegar el sitio**:
62+
```bash
63+
# Los cambios se aplicarán automáticamente en el próximo deploy
64+
git push origin main
65+
```
66+
67+
## Verificación
68+
69+
Después del despliegue, verificar que funcionen:
70+
-`https://pythoncdmx.org/meetups/`
71+
-`https://pythoncdmx.org/meetups/index.html`
72+
-`https://pythoncdmx.org/about/`
73+
-`https://pythoncdmx.org/about/index.html`
74+
75+
## Notas Técnicas
76+
77+
- La CloudFront Function se ejecuta en el edge, por lo que tiene latencia mínima
78+
- La función solo modifica la URI si es necesario, sin afectar assets estáticos
79+
- Los cache behaviors mantienen sus configuraciones originales de TTL
80+
- La solución es compatible con el comportamiento existente de MkDocs
81+
82+
## Referencias
83+
84+
- [MkDocs use_directory_urls documentation](https://www.mkdocs.org/user-guide/configuration/#use_directory_urls)
85+
- [CloudFront Functions documentation](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/cloudfront-functions.html)

mkdocs.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ repo_url: https://github.com/PythonMexico/pythonCDMX/
1111
# Copyright
1212
copyright: Copyright © 2025 Python CDMX
1313

14+
# URL configuration
15+
use_directory_urls: true
16+
1417
# Theme configuration
1518
theme:
1619
name: material

terraform/cloudfront.tf

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,31 @@ resource "aws_cloudfront_origin_access_control" "website" {
77
signing_protocol = "sigv4"
88
}
99

10+
# CloudFront Function to handle URLs without .html extension
11+
resource "aws_cloudfront_function" "url_rewrite" {
12+
name = "pythoncdmx-url-rewrite"
13+
runtime = "cloudfront-js-1.0"
14+
comment = "Rewrite URLs without .html extension"
15+
publish = true
16+
code = <<-EOT
17+
function handler(event) {
18+
var request = event.request;
19+
var uri = request.uri;
20+
21+
// If the URI ends with a slash, try to serve index.html
22+
if (uri.endsWith('/')) {
23+
request.uri = uri + 'index.html';
24+
}
25+
// If the URI doesn't have an extension, try to add .html
26+
else if (!uri.includes('.') && !uri.endsWith('/')) {
27+
request.uri = uri + '.html';
28+
}
29+
30+
return request;
31+
}
32+
EOT
33+
}
34+
1035
# CloudFront distribution
1136
resource "aws_cloudfront_distribution" "website" {
1237
enabled = true
@@ -42,6 +67,12 @@ resource "aws_cloudfront_distribution" "website" {
4267
default_ttl = 3600 # 1 hour
4368
max_ttl = 86400 # 24 hours
4469
compress = true
70+
71+
# Associate CloudFront Function for URL rewriting
72+
function_association {
73+
event_type = "viewer-request"
74+
function_arn = aws_cloudfront_function.url_rewrite.arn
75+
}
4576
}
4677

4778
# Cache behavior for static assets (images, CSS, JS)
@@ -63,6 +94,12 @@ resource "aws_cloudfront_distribution" "website" {
6394
default_ttl = 86400 # 24 hours
6495
max_ttl = 31536000 # 1 year
6596
compress = true
97+
98+
# Associate CloudFront Function for URL rewriting
99+
function_association {
100+
event_type = "viewer-request"
101+
function_arn = aws_cloudfront_function.url_rewrite.arn
102+
}
66103
}
67104

68105
ordered_cache_behavior {
@@ -83,6 +120,12 @@ resource "aws_cloudfront_distribution" "website" {
83120
default_ttl = 86400 # 24 hours
84121
max_ttl = 31536000 # 1 year
85122
compress = true
123+
124+
# Associate CloudFront Function for URL rewriting
125+
function_association {
126+
event_type = "viewer-request"
127+
function_arn = aws_cloudfront_function.url_rewrite.arn
128+
}
86129
}
87130

88131
ordered_cache_behavior {
@@ -103,6 +146,12 @@ resource "aws_cloudfront_distribution" "website" {
103146
default_ttl = 604800 # 7 days
104147
max_ttl = 31536000 # 1 year
105148
compress = true
149+
150+
# Associate CloudFront Function for URL rewriting
151+
function_association {
152+
event_type = "viewer-request"
153+
function_arn = aws_cloudfront_function.url_rewrite.arn
154+
}
106155
}
107156

108157
# Custom error responses for SPA-like behavior

0 commit comments

Comments
 (0)