Skip to content

Commit a728f87

Browse files
alephclaude
andcommitted
fix: merge staging and correct CloudFront function logic for MkDocs
Merge changes from staging branch and fix the URL rewriting logic to correctly handle MkDocs directory URLs. Changes: - Merge staging branch (commits a111f61, e9b294a) - Remove duplicate cloudfront-function.tf (use unified url_rewrite function) - Fix url_rewrite function: change '.html' to '/index.html' for URLs without extension - Update documentation to reflect correct behavior - Integrate mkdocs.yml changes from staging The corrected logic now properly handles MkDocs use_directory_urls: - /meetups → /meetups/index.html (was incorrectly /meetups.html) - /meetups/ → /meetups/index.html (already correct) This ensures all directory URLs work correctly in both production and staging. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
2 parents 9dd2f31 + e9b294a commit a728f87

File tree

5 files changed

+180
-69
lines changed

5 files changed

+180
-69
lines changed

docs/URL_FIX_DOCUMENTATION.md

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
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, append index.html
28+
if (uri.endsWith('/')) {
29+
request.uri = uri + 'index.html';
30+
}
31+
// If the URI doesn't have an extension, append /index.html
32+
else if (!uri.includes('.') && !uri.endsWith('/')) {
33+
request.uri = uri + '/index.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+
3. **terraform/cloudfront-staging.tf**:
50+
- Aplicada la misma CloudFront Function a staging
51+
- Asociada la función con todos los cache behaviors de staging
52+
53+
## Despliegue
54+
55+
Para aplicar estos cambios:
56+
57+
1. **Aplicar cambios de Terraform**:
58+
```bash
59+
cd terraform
60+
terraform plan
61+
terraform apply
62+
```
63+
64+
2. **Desplegar el sitio**:
65+
```bash
66+
# Los cambios se aplicarán automáticamente en el próximo deploy
67+
git push origin main
68+
```
69+
70+
## Verificación
71+
72+
Después del despliegue, verificar que funcionen:
73+
74+
### Producción
75+
-`https://pythoncdmx.org/meetups/`
76+
-`https://pythoncdmx.org/meetups/index.html`
77+
-`https://pythoncdmx.org/about/`
78+
-`https://pythoncdmx.org/about/index.html`
79+
80+
### Staging
81+
-`https://staging.pythoncdmx.org/meetups/`
82+
-`https://staging.pythoncdmx.org/meetups/index.html`
83+
-`https://staging.pythoncdmx.org/about/`
84+
-`https://staging.pythoncdmx.org/about/index.html`
85+
86+
## Notas Técnicas
87+
88+
- La CloudFront Function se ejecuta en el edge, por lo que tiene latencia mínima
89+
- La función solo modifica la URI si es necesario, sin afectar assets estáticos
90+
- Los cache behaviors mantienen sus configuraciones originales de TTL
91+
- La solución es compatible con el comportamiento existente de MkDocs
92+
93+
## Referencias
94+
95+
- [MkDocs use_directory_urls documentation](https://www.mkdocs.org/user-guide/configuration/#use_directory_urls)
96+
- [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 &copy; 2025 Python CDMX
1313

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

terraform/cloudfront-function.tf

Lines changed: 0 additions & 52 deletions
This file was deleted.

terraform/cloudfront-staging.tf

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

10+
# CloudFront Function for staging (reuse the same function as production)
11+
# Note: CloudFront Functions are global, so we can reference the same function
12+
1013
# CloudFront distribution for staging
1114
resource "aws_cloudfront_distribution" "website_staging" {
1215
enabled = true
@@ -39,14 +42,14 @@ resource "aws_cloudfront_distribution" "website_staging" {
3942

4043
viewer_protocol_policy = "redirect-to-https"
4144
min_ttl = 0
42-
default_ttl = 300 # 5 minutes - shorter cache for staging
43-
max_ttl = 3600 # 1 hour - shorter cache for staging
45+
default_ttl = 300 # 5 minutes - shorter cache for staging
46+
max_ttl = 3600 # 1 hour - shorter cache for staging
4447
compress = true
4548

46-
# Associate CloudFront Function for directory index rewriting
49+
# Associate CloudFront Function for URL rewriting (same as production)
4750
function_association {
4851
event_type = "viewer-request"
49-
function_arn = aws_cloudfront_function.directory_index_staging.arn
52+
function_arn = aws_cloudfront_function.url_rewrite.arn
5053
}
5154
}
5255

@@ -66,9 +69,15 @@ resource "aws_cloudfront_distribution" "website_staging" {
6669

6770
viewer_protocol_policy = "redirect-to-https"
6871
min_ttl = 0
69-
default_ttl = 1800 # 30 minutes
70-
max_ttl = 7200 # 2 hours
72+
default_ttl = 1800 # 30 minutes
73+
max_ttl = 7200 # 2 hours
7174
compress = true
75+
76+
# Associate CloudFront Function for URL rewriting
77+
function_association {
78+
event_type = "viewer-request"
79+
function_arn = aws_cloudfront_function.url_rewrite.arn
80+
}
7281
}
7382

7483
# Cache behavior for static assets (JS) - shorter cache for staging
@@ -87,9 +96,15 @@ resource "aws_cloudfront_distribution" "website_staging" {
8796

8897
viewer_protocol_policy = "redirect-to-https"
8998
min_ttl = 0
90-
default_ttl = 1800 # 30 minutes
91-
max_ttl = 7200 # 2 hours
99+
default_ttl = 1800 # 30 minutes
100+
max_ttl = 7200 # 2 hours
92101
compress = true
102+
103+
# Associate CloudFront Function for URL rewriting
104+
function_association {
105+
event_type = "viewer-request"
106+
function_arn = aws_cloudfront_function.url_rewrite.arn
107+
}
93108
}
94109

95110
# Cache behavior for images - shorter cache for staging
@@ -108,9 +123,15 @@ resource "aws_cloudfront_distribution" "website_staging" {
108123

109124
viewer_protocol_policy = "redirect-to-https"
110125
min_ttl = 0
111-
default_ttl = 3600 # 1 hour
112-
max_ttl = 86400 # 24 hours
126+
default_ttl = 3600 # 1 hour
127+
max_ttl = 86400 # 24 hours
113128
compress = true
129+
130+
# Associate CloudFront Function for URL rewriting
131+
function_association {
132+
event_type = "viewer-request"
133+
function_arn = aws_cloudfront_function.url_rewrite.arn
134+
}
114135
}
115136

116137
# Custom error responses for SPA-like behavior

terraform/cloudfront.tf

Lines changed: 50 additions & 7 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 directory URLs for MkDocs
11+
resource "aws_cloudfront_function" "url_rewrite" {
12+
name = "pythoncdmx-url-rewrite"
13+
runtime = "cloudfront-js-1.0"
14+
comment = "Rewrite directory URLs to include index.html for MkDocs"
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, append index.html
22+
if (uri.endsWith('/')) {
23+
request.uri = uri + 'index.html';
24+
}
25+
// If the URI doesn't have an extension, append /index.html
26+
else if (!uri.includes('.') && !uri.endsWith('/')) {
27+
request.uri = uri + '/index.html';
28+
}
29+
30+
return request;
31+
}
32+
EOT
33+
}
34+
1035
# CloudFront distribution
1136
resource "aws_cloudfront_distribution" "website" {
1237
enabled = true
@@ -39,14 +64,14 @@ resource "aws_cloudfront_distribution" "website" {
3964

4065
viewer_protocol_policy = "redirect-to-https"
4166
min_ttl = 0
42-
default_ttl = 3600 # 1 hour
43-
max_ttl = 86400 # 24 hours
67+
default_ttl = 3600 # 1 hour
68+
max_ttl = 86400 # 24 hours
4469
compress = true
4570

46-
# Associate CloudFront Function for directory index rewriting
71+
# Associate CloudFront Function for URL rewriting
4772
function_association {
4873
event_type = "viewer-request"
49-
function_arn = aws_cloudfront_function.directory_index.arn
74+
function_arn = aws_cloudfront_function.url_rewrite.arn
5075
}
5176
}
5277

@@ -66,9 +91,15 @@ resource "aws_cloudfront_distribution" "website" {
6691

6792
viewer_protocol_policy = "redirect-to-https"
6893
min_ttl = 0
69-
default_ttl = 86400 # 24 hours
94+
default_ttl = 86400 # 24 hours
7095
max_ttl = 31536000 # 1 year
7196
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+
}
72103
}
73104

74105
ordered_cache_behavior {
@@ -86,9 +117,15 @@ resource "aws_cloudfront_distribution" "website" {
86117

87118
viewer_protocol_policy = "redirect-to-https"
88119
min_ttl = 0
89-
default_ttl = 86400 # 24 hours
120+
default_ttl = 86400 # 24 hours
90121
max_ttl = 31536000 # 1 year
91122
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+
}
92129
}
93130

94131
ordered_cache_behavior {
@@ -106,9 +143,15 @@ resource "aws_cloudfront_distribution" "website" {
106143

107144
viewer_protocol_policy = "redirect-to-https"
108145
min_ttl = 0
109-
default_ttl = 604800 # 7 days
146+
default_ttl = 604800 # 7 days
110147
max_ttl = 31536000 # 1 year
111148
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+
}
112155
}
113156

114157
# Custom error responses for SPA-like behavior

0 commit comments

Comments
 (0)