Angular Desarrollo web google Herramientas Utiles javascript Typescript wordpress

Cómo construí el frontend de Hackeruna en Angular 20 y lo dejé listo para Google AdSense

Cómo construí el frontend de Hackeruna en Angular 20 y lo dejé listo para Google AdSense

Hackeruna siempre fue mi laboratorio de pruebas: escribo sobre Angular, Laravel, DevOps y ahora también lo utilizo como campo de batalla para experimentar con arquitecturas modernas. En esta última iteración decidí reescribir el frontend completo en Angular 20, usando WordPress solo como headless CMS, y dejarlo totalmente optimizado para Google AdSense.

En este post te cuento, como desarrollador full stack con varios años trabajando con Angular, cómo está montado el proyecto ng-hackeruna, qué decisiones tomé a nivel de arquitectura y qué ajustes fueron clave para que AdSense aceptara la web sin problemas de rendimiento, SEO ni políticas. El objetivo es que puedas replicar la misma idea en tu propio blog técnico.


Arquitectura general: Angular 20 + WordPress como headless CMS

La base del proyecto es sencilla pero potente:

  • Frontend: Angular 20 con standalone components y TypeScript estricto.
  • Estilos: Tailwind CSS 4 con un pequeño design system para botones, tipografía y layout.
  • Backend de contenido: WordPress, usado como REST API para posts, categorías y páginas legales.
  • Testing: Vitest para pruebas unitarias y de servicios.
  • Objetivo: un frontend moderno, rápido y SEO friendly para un blog de tecnología, con soporte para AdSense y otras integraciones de analítica.

Angular consume los posts, categorías y páginas legales desde los endpoints REST de WordPress, y los renderiza como una SPA con rutas bien definidas (/, /post/:slug, /categoria/:slug, /about, /privacidad, etc.). De esta forma, el contenido lo mantengo en WordPress (editor clásico o Gutenberg) y el front tiene total libertad de diseño y performance.


Configuración base de Angular para un blog rápido y mantenible

El proyecto de Angular se generó con la CLI oficial y luego lo fui adaptando al stack actual:

  • Angular 20 con componentes standalone (sin módulos clásicos).
  • Ruteo separado por features: home, posts, categorías, páginas legales.
  • Servicios dedicados para WordPress (posts, categorías, páginas).
  • Modo estricto en TypeScript para controlar mejor tipos y errores.

Un ejemplo simplificado del routing principal puede verse así:

<!-- app.routes.ts -->
import { Routes } from '@angular/router';
import { HomePageComponent } from './features/home/home-page.component';
import { PostDetailPageComponent } from './features/post/post-detail-page.component';
import { CategoryPageComponent } from './features/category/category-page.component';
import { LegalPageComponent } from './features/legal/legal-page.component';

export const routes: Routes = [
  { path: '', component: HomePageComponent, title: 'Hackeruna - Blog de Tecnología' },
  { path: 'post/:slug', component: PostDetailPageComponent },
  { path: 'categoria/:slug', component: CategoryPageComponent },
  { path: 'page/:slug', component: LegalPageComponent },
  { path: '**', redirectTo: '' }
];

Y un servicio básico para consumir la API de WordPress:

<!-- wp-posts.service.ts -->
import { inject, Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable({ providedIn: 'root' })
export class WpPostsService {
  private http = inject(HttpClient);
  private readonly apiUrl = 'https://hackeruna.com/wp-json/wp/v2';

  getLatestPosts(): Observable<any[]> {
    return this.http.get<any[]>(`${this.apiUrl}/posts?per_page=10`);
  }

  getPostBySlug(slug: string): Observable<any[]> {
    return this.http.get<any[]>(`${this.apiUrl}/posts?slug=${slug}`);
  }
}

Con esta base ya tenía el front corriendo contra WordPress, pero para que AdSense lo apruebe no basta con “que funcione”; hay que cumplir requisitos técnicos y de calidad.


Performance y SEO: checklist antes de hablar de AdSense

Google AdSense mira dos cosas muy de cerca: calidad de contenido y experiencia de usuario. La segunda se traduce directamente en rendimiento (Core Web Vitals) y SEO técnico. Para eso en ng-hackeruna apliqué varias optimizaciones:

  • Lazy loading de rutas y componentes pesados (por ejemplo, páginas de detalle de post, componentes de vídeo, etc.).
  • Imágenes optimizadas y uso de loading="lazy" en portadas y miniaturas.
  • Tailwind para tener CSS minimalista, eliminando clases no usadas en el build de producción.
  • TypeScript estricto y arquitectura limpia para evitar bugs raros en producción.
  • Páginas legales completas: aviso de privacidad, cookies, términos y contacto.

El resultado: un frontend ligero, con buenas métricas de LCP y CLS, y una estructura clara que Google puede rastrear sin problemas. Con esto la base para AdSense ya estaba mucho más sólida.


Integrando Google AdSense en un proyecto Angular (sin romper nada)

El siguiente reto fue integrar AdSense en un entorno SPA con Angular, donde el contenido cambia por rutas de cliente, pero Google sigue esperando un comportamiento “clásico” de páginas HTML. La clave está en:

  1. Cargar el script de AdSense solo una vez.
  2. Encapsular los bloques de anuncio en un componente Angular reutilizable.
  3. Volver a push sobre adsbygoogle cuando cambias de ruta.

1. Script principal de AdSense

Primero, en index.html (o en el shell principal) añadí el script global de AdSense con mi client:

<!-- index.html -->
<head>
  <meta charset="utf-8" />
  <title>Hackeruna - Blog de Tecnología</title>

  <script async
          src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-XXXXXXXXXXXXXXX"
          crossorigin="anonymous"></script>
</head>

El client es el ID de editor que te da AdSense cuando añades tu sitio. Este script solo se incluye una vez; el resto lo gestiona un componente especializado.

2. Componente <app-adsense-banner> reutilizable

Para no repetir el bloque de anuncio por todo el proyecto, creé un componente standalone específico para AdSense:

<!-- adsense-banner.component.ts -->
import { AfterViewInit, Component, Input } from '@angular/core';

declare global {
  interface Window {
    adsbygoogle: any[];
  }
}

@Component({
  selector: 'app-adsense-banner',
  standalone: true,
  template: `
    <ins class="adsbygoogle"
         style="display:block"
         [attr.data-ad-client]="adClient"
         [attr.data-ad-slot]="adSlot"
         data-ad-format="auto"
         data-full-width-responsive="true"></ins>
  `
})
export class AdsenseBannerComponent implements AfterViewInit {
  @Input() adClient = 'ca-pub-XXXXXXXXXXXXXXX';
  @Input() adSlot!: string;

  ngAfterViewInit(): void {
    try {
      (window.adsbygoogle = window.adsbygoogle || []).push({});
    } catch (e) {
      console.warn('Adsense error', e);
    }
  }
}

Y luego lo uso en las plantillas donde quiero anuncios, por ejemplo, entre el listado de posts:

<!-- home-page.component.html -->
<section class="posts-grid">
  <article *ngFor="let post of posts; let i = index">
    <app-post-card [post]="post"></app-post-card>

    <!-- Inserto un banner cada 3 posts -->
    <app-adsense-banner
      *ngIf="(i + 1) % 3 === 0"
      adSlot="1234567890">
    </app-adsense-banner>
  </article>
</section>

De esta forma, Angular controla dónde aparecen los anuncios, pero el comportamiento sigue siendo el esperado por AdSense: ins, clase adsbygoogle y un push después de montar el componente.


ads.txt, políticas y “readiness” para AdSense

Además del código, AdSense valida que tu sitio cumpla ciertos requisitos de política y transparencia:

  • El dominio debe estar verificado en tu cuenta de AdSense.
  • Debes tener páginas de Privacidad, Cookies y Términos accesibles desde el menú o el footer.
  • Es recomendable publicar el archivo ads.txt en la raíz del dominio.

El archivo ads.txt se ve así:

# ads.txt en https://hackeruna.com/ads.txt
google.com, pub-XXXXXXXXXXXXXXX, DIRECT, f08c47fec0942fa0

La línea indica que Google (AdSense) está autorizado a vender inventario publicitario en tu dominio. El ID de publisher debe ser exactamente el mismo que utilizas en el script de AdSense.

Por el lado de contenido, en WordPress mantengo:

  • Una página de Política de Privacidad donde explico el uso de cookies, AdSense y herramientas de analítica.
  • Una página de Términos y Condiciones del blog.
  • Una sección clara de contacto.

Todo esto se expone vía REST y Angular lo muestra como páginas legales dentro de la misma interfaz, mejorando la experiencia de usuario y cumpliendo las políticas.


Optimización final: dónde coloco los anuncios y cómo no matar la UX

Algo que aprendí con Hackeruna es que no se trata solo de activar anuncios, sino de hacerlo sin destruir la experiencia de lectura del blog. Las decisiones que tomé fueron:

  • Colocar anuncios:
    • Entre tarjetas de posts en la home (cada X elementos).
    • Dentro de los posts largos, después de ciertos bloques de contenido.
    • En el sidebar solo en desktop, para no saturar el móvil.
  • Evitar anuncios justo en el hero principal o encima del título del post.
  • Comprobar en móvil que los anuncios no rompan el layout ni provoquen desplazamientos inesperados (CLS alto).

Gracias a la combinación de Angular 20, un front ligero y una distribución cuidadosa de los anuncios, AdSense aprobó el sitio y los ingresos comenzaron a llegar sin sacrificar la experiencia del lector.


Cómo puedes aplicar este enfoque en tu propio proyecto

Si quieres replicar este patrón (Angular + WordPress + AdSense), el flujo recomendado es:

  1. Montar WordPress como headless (con el REST API activo y las páginas legales creadas).
  2. Crear un frontend en Angular 16+ (idealmente 17–20) con:
    • Rutas para home, posts, categorías y legales.
    • Servicios para consumir la API de WordPress.
  3. Optimizar performance: lazy loading, imágenes, CSS reducido, build de producción.
  4. Configurar AdSense:
    • Verificar dominio en la cuenta de AdSense.
    • Agregar el script global y el archivo ads.txt.
    • Crear un componente de anuncio reutilizable.
  5. Revisar que las páginas legales expliquen claramente el uso de cookies, AdSense y analítica.

Con este enfoque, conviertes un blog clásico en una plataforma moderna: Angular se encarga de la experiencia, WordPress de la gestión de contenido y AdSense de monetizar el tráfico sin que el proyecto se convierta en un monstruo difícil de mantener.

Si estás pensando en migrar tu blog técnico a una arquitectura similar, Hackeruna es la prueba de que se puede hacer de forma limpia, escalable y lista para monetizar.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *