Your website is slow or out of date: I fix it or build you a new one

First I review it for free and tell you what’s wrong. If it can be fixed, I send you a fixed quote. If a new one makes more sense, I rebuild it with one of the plans, move your content over and keep your Google traffic at no extra cost.

Who it is for

  • Sites that take a long time to load and lose visitors for it
  • Sites where updating a plugin is frightening
  • Anyone who has lost Google rankings since the last change

Who it is not for

  • Brand-new sites whose problem is the content, not the code
  • Shops with complex WooCommerce logic: that calls for custom development

How I do it

What I change when I review a site.

Seven examples of the kind of change a review produces. On the left what tends to be there; on the right what I leave. The code is illustrative: the problems are the usual ones.

Choose a fix
Performance3
Accessibility2
Security2
Editor theme
index.htmlcss/listado.csssrc/lib/listado.tspartials/menu.htmlcontacto.htmlwp-content/themes/casa/tarjeta.phpsrc/pages/api/contacto.ts
Before and after of index.html
                     <!-- Portada: la imagen es lo primero que se pinta. --> <section class="hero grid gap-6 py-24">-  <img src="portada.jpg" class="w-full rounded-xl">+  <img src="portada.avif" class="w-full rounded-xl"+       width="1600" height="900" decoding="async"+       fetchpriority="high" alt="Cocina en Chamberí">   <h1 class="text-5xl font-semibold tracking-tight">     Reformas integrales en Madrid, sin sorpresas   </h1>   <p class="max-w-prose text-lg text-neutral-400">     Presupuesto cerrado en 48 horas laborables.   </p>   <a href="/contacto" class="btn">Pedir presupuesto</a> </section>
                  
Before and after of css/listado.css
                     .listado { display: grid; gap: 1rem; } -/* Tres saltos, y ninguno sabe cuánto sitio hay. */+/* La tarjeta mide su hueco, no la ventana. */-.tarjeta { padding: 16px; font-size: 18px; }+.listado { container-type: inline-size; }-+-@media (max-width: 900px) {+.tarjeta {-  .tarjeta { padding: 12px; font-size: 16px; }+  padding: clamp(0.5rem, 2cqi, 1rem);-}+  font-size: clamp(0.875rem, 1.6cqi, 1.125rem);-+  border-radius: clamp(0.25rem, 1cqi, 0.75rem);-@media (max-width: 600px) {+}-  .tarjeta { padding: 8px; font-size: 14px; }+-}+@container (min-width: 30rem) {+  .tarjeta { grid-template-columns: 8rem 1fr; }+}
                  
Before and after of src/lib/listado.ts
                     export async function cargarListado() {   const items = await db.producto.findMany({     where: { activo: true },+    // La categoría entra en la misma ida.+    include: { categoria: true },   }); -  // Una consulta, y luego otra por item.-  for (const item of items) {-    item.categoria = await db.categoria-      .findUnique({ id: item.categoriaId });-  }    return items; }
                  
Before and after of partials/menu.html
                    -<div class="menu__abrir"+<button class="menu__abrir"-     onclick="abrirMenu()">+        type="button"+        aria-expanded="false"+        aria-controls="menu">+  <span class="sr-only">Abrir el menú</span>   <span></span>   <span></span>-</div>+</button>  <nav id="menu" class="menu">   <a href="/servicios">Servicios</a>   <a href="/proyectos">Proyectos</a>   <a href="/precios">Precios</a>   <a href="/contacto">Contacto</a> </nav>
                  
Before and after of contacto.html
                     <form method="post" action="/contacto">   <label for="email">Correo</label>-  <input id="email" type="email"+  <input id="email" type="email"-         name="email">+         name="email"+         aria-invalid="true"+         aria-describedby="email-error"> -  <span class="error">+  <span class="error" id="email-error"+        role="alert">     Escribe un correo válido   </span>    <button type="submit">Enviar</button> </form>
                  
Before and after of wp-content/themes/casa/tarjeta.php
                     <section class="listado"> <?php foreach ( $productos as $p ) : ?> <article class="tarjeta">-  <img src="<?php echo $p['imagen']; ?>" alt="">+  <img src="<?php echo esc_url( $p['imagen'] ); ?>"-  <h2><?php echo $p['nombre']; ?></h2>+       alt="<?php echo esc_attr( $p['nombre'] ); ?>">-  <p><?php echo $p['descripcion']; ?></p>+  <h2><?php echo esc_html( $p['nombre'] ); ?></h2>-  <a href="<?php echo $p['url']; ?>">+  <p><?php echo wp_kses_post( $p['descripcion'] ); ?></p>-    Ver ficha de <?php echo $p['nombre']; ?>+  <a href="<?php echo esc_url( $p['url'] ); ?>">-  </a>+    Ver ficha de <?php echo esc_html( $p['nombre'] ); ?>+  </a> </article> <?php endforeach; ?> </section>
                  
Before and after of src/pages/api/contacto.ts
                     // El esquema estaba escrito y no lo miraba nadie. const Lead = z.object({   nombre: z.string().min(2).max(80),   email: z.email(),   mensaje: z.string().min(10).max(2000), });  export async function POST({ request }) {-  const datos = await request.json();+  const lead = Lead.safeParse(await request.json());-  await guardarLead(datos);+  if (!lead.success) {+    return new Response(null, { status: 422 });+  }+  await guardarLead(lead.data);   return new Response(null, { status: 204 }); }
                  

Where to start

  1. First

    Website X-ray

    free

    I look at your site and within 48 working hours tell you what is wrong and what I would fix first.

    Request X-ray
  2. Then

    Rebuild your old site

    €590from

    If yours can’t be fixed, I rebuild it with one of the plans. I move your content over and keep your Google traffic at no extra cost.

    Get a free quote
  3. To make it last

    Ongoing maintenance

    €49per month

    Backups, updates, security and an alert if the site goes down, from the first month. Three tiers, depending on how much you want to change each month.

    See pricing

Shall we talk about your project?

Tell me what you need and I will send a first assessment within 24 working hours.

Reply within 24 working hours