---
title: "Blogs de miembros"
description: "Cada miembro con nombre de usuario obtiene un espacio de publicación personal en /{username}/{slug}. Escritura según el rol, el espacio de trabajo /my-news, el listado por autor, las propuestas de revisión y la promoción de pago al feed principal mediante News Kingdom. Nota de migración para las URL retiradas /blog/{username}."
locale: "es"
---
# Blogs de miembros

> **Info**
> **Cambio de URL:** los artículos de los miembros ahora viven en `/{username}/{slug}`, junto al perfil del miembro en `/{username}`. El patrón anterior `/blog/{username}/{slug}` ya no existe y no hay ninguna ruta `/blog`. Usa las pestañas **Fundador** / **Desarrollador** de la barra lateral para filtrar esta página.

Los blogs de miembros convierten el módulo de noticias de tu clon en un espacio de publicación para cada miembro. Los artículos se guardan en la misma tabla `news` que las noticias oficiales, se etiquetan con el identificador del autor y se sirven en la URL propia del autor. Si un autor quiere llegar al feed principal, solicita la promoción y el artículo entra en el pipeline de [News Kingdom](/docs/architecture/news-kingdom.md).

| La documentación anterior decía | Comportamiento actual |
|-------------------|------------------|
| `/blog/{username}` y `/blog/{username}/{slug}` | `/{username}` (perfil) y `/{username}/{slug}` (artículo) |
| La membresía de pago desbloquea el blog | Para escribir se necesita el rol `member` o superior. Una mejora de membresía de pago otorga `member` |
| El perfil muestra un enlace al blog y una insignia de Telegram | No está en la página de perfil actual. Los autores comparten su enlace desde `/my-news` |
| Sin membresía, la ruta del blog devuelve 404 | Un artículo devuelve 404 cuando no está publicado, el identificador o el slug no coinciden, o el idioma es distinto |

### For founders

## Por qué importa para tu clon

- **Los miembros se convierten en editores.** Cada miembro de pago obtiene un espacio personal con una URL limpia y fácil de compartir bajo tu dominio.
- **Una sola identidad.** El mismo nombre de usuario reúne el perfil, los artículos y el listado del autor.
- **Un embudo de contenido que tú controlas.** Las buenas publicaciones pueden promocionarse a tu portada a cambio de una tarifa. Tú apruebas cada una.
- **Los lectores ayudan a mejorar las publicaciones.** Otros miembros pueden proponer revisiones. El autor decide qué acepta.

  
- **[News Kingdom](/docs/architecture/news-kingdom.md)** — Puntuación, promoción de pago y aprobación en Telegram para el feed principal.

  
- **[Perfil público](/docs/features/public-profile.md)** — La página `/{username}` que está junto a los artículos del miembro.

  
- **[Reserva de nombres de usuario](/docs/features/username-reservation.md)** — Los identificadores determinan las URL de los blogs, así que los nombres reservados importan.

  
- **[Suscripciones](/docs/features/subscriptions.md)** — La vía de pago que eleva a un usuario al rol `member`.

### Escenarios típicos

1. **Comunidad de expertos.** Los miembros escriben textos extensos con su propio identificador y los mejores se promocionan a la portada.
2. **Boletín cooperativo.** Cada productor mantiene un blog. El equipo de administración elige historias para el feed principal.
3. **Incentivo de membresía.** Los usuarios gratuitos pueden leer. Escribir es una ventaja de la membresía de pago.

### Dónde trabajan los miembros

| Superficie | Ruta |
|---------|------|
| Escribir un artículo nuevo | `/news/create` |
| Gestionar, compartir y promocionar | `/my-news` |
| Artículo público | `/{username}/{slug}` |
| Todos los artículos de un autor | `/news/author/{username}` |

### For developers

## Rutas y módulos (verificado en `ring/web`)

| Aspecto | Ruta |
|---------|------|
| Página del artículo | `app/[locale]/[username]/[slug]/page.tsx` |
| Página del perfil | `app/[locale]/[username]/page.tsx` |
| Listado por autor | `app/[locale]/news/author/[username]/page.tsx` (hasta 50 publicados, mediante `getMyArticles`) |
| Editor del miembro | `app/[locale]/(protected)/news/create/page.tsx` (`ArticleEditor audience="member"`) |
| Espacio de trabajo del miembro | `app/[locale]/(protected)/my-news/` con `components/layout/rails/my-news-rail.tsx` |
| Bandeja de enmiendas | `/my-news/{articleId}/amendments` (`ROUTES.MY_NEWS_AMENDMENTS`) |
| Utilidades de identificador y ruta | `lib/blog/blog-path.ts` (`normalizeBlogHandle`, `profileArticlePathname`, `profileArticleHref`) |
| URL absoluta | `lib/site-branding.ts` `localeBlogArticleUrl(locale, username, slug)` |
| Acción de guardado | `app/_actions/news.ts` |
| Permisos | `features/news/lib/news-permissions.ts` |

## Cómo se resuelve un artículo

La página del artículo busca una fila en `news` que cumpla los cuatro filtros: `blogUsername == normalizeBlogHandle(username)`, `slug`, `locale` y `status == 'published'`. Si ninguna fila coincide, llama a `notFound()` y los metadatos pasan a `noindex`. Los identificadores se guardan con una `@` inicial, así que `/en/alice/hello` busca `blogUsername: '@alice'`.

> **Warning**
> `blogUsername` solo se asigna al **crear** el artículo, y solo cuando el usuario de la sesión tiene nombre de usuario. Los artículos escritos antes de que el autor eligiera un nombre de usuario nunca reciben identificador, así que no se resolverán en `/{username}/{slug}`. Para este caso, el panel de `/my-news` muestra un aviso para definir el nombre de usuario.

Las rutas estáticas como `/store`, `/news` o `/about` tienen prioridad sobre el segmento dinámico `[username]`. Un nombre de usuario que coincida con una ruta estática no puede tener una URL de perfil.

## Permisos

| Acción | Regla |
|--------|------|
| Crear | `canCreateNewsArticle`: rol `member` o superior, administrador de la plataforma o `confidential` |
| Editar o eliminar | Administrador de la plataforma o el autor del artículo |
| Visibilidad `site-wide` | Solo administradores de la plataforma. Los miembros llegan a ella mediante la aprobación de la promoción |
| Visibilidad `confidential` | Solo usuarios con acceso confidencial |
| `featured` | Se fuerza a `false` al guardar para quienes no son administradores |
| Proponer una revisión | Usuario con sesión iniciada que no es el autor, con `canProposeRevision`, en artículos publicados |

## Escribir, publicar, promocionar

**Crear**

Un miembro abre `/news/create`. Al guardar, `app/_actions/news.ts` escribe el artículo mediante `createNewsArticle()` con `blogUsername` y registra el primer commit de versión (`lib/versioning`).

**Publicar y compartir**

Fija `status: 'published'`. El panel de `/my-news` construye el enlace público a partir de `ROUTES.PUBLIC_PROFILE(handle)` y ofrece un botón para copiar el enlace.

**Promocionar (opcional)**

`features/news/components/news-promotion-panel.tsx` llama a `POST /api/news/promotion/submit` con `{ articleId }`. Solo el autor puede enviarlo. Consulta [News Kingdom](/docs/architecture/news-kingdom.md) para la puntuación, el pago y la aprobación.

Cada visita a un artículo la cuenta `recordArticlePageView()` dentro de `after()`, así que el recuento nunca bloquea el renderizado.

## Preguntas frecuentes

### Migración

#### ¿Seguirán funcionando los enlaces antiguos /blog?

No. En `ring/web` no hay ninguna ruta `/blog` ni redirección. Actualiza los enlaces compartidos a `/{username}/{slug}`.

### Impacto

#### ¿Pueden los lectores guardar artículos de miembros en favoritos?

Los favoritos funcionan mediante `GET` y `POST /api/user/favorites` con el hook `useContentFavorite`. Ese hook está conectado a la vista de artículo de noticias (`components/wrappers/news-article-wrapper.tsx`), no a la página `/{username}/{slug}`.

## Carencias conocidas

## Documentación relacionada

  
- [architecture/news-kingdom](/docs/architecture/news-kingdom.md) — Siguiente paso: qué ocurre después de que un autor solicita la promoción a la página principal.

  
- [features/news](/docs/features/news.md) — Requisito previo: el módulo de noticias que guarda y muestra los artículos de los miembros.

  
- [features/public-profile](/docs/features/public-profile.md) — Mismo flujo: la página /{username} que comparte el identificador del miembro.

  
- [features/username-reservation](/docs/features/username-reservation.md) — Depende de: cómo se eligen y protegen los identificadores, que deciden las URL de los blogs.
