Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/santiagodc8/tu_perfil.net/llms.txt

Use this file to discover all available pages before exploring further.

Readers can search for articles across the entire site using the search page at /buscar.

URL

/buscar?q={query}&cat={category-slug}&sort={recent|oldest|popular}
All parameters are optional. Visiting /buscar with no query shows an empty search form with no results. Examples:
  • /buscar?q=elecciones — search for “elecciones” across all categories
  • /buscar?q=hospital&cat=perfil-salud&sort=popular — search in Perfil Salud, sorted by most read

Search behavior

Search is performed entirely on the server (no client-side fetch). The page is a Next.js server component that reads searchParams and runs a Supabase query on each request. The query matches against three fields using case-insensitive ilike:
src/app/(public)/buscar/page.tsx
let qb = supabase
  .from("articles")
  .select(
    "title, slug, excerpt, image_url, created_at, views, category:categories(name, color)"
  )
  .eq("published", true)
  .or(
    `title.ilike.%${query}%,excerpt.ilike.%${query}%,content.ilike.%${query}%`
  );
Search matches on title, excerpt, and content (the full article body). Results are limited to 30 articles per search.

Filters and sort

After the search box, two dropdown filters let the reader narrow results:

Category filter

A <select> populated with all categories from the database. Selecting a category adds cat={slug} to the query and restricts results to articles in that category.

Sort order

Three sort options: Más recientes (recent, default), Más antiguas (oldest), and Más leídas (popular). Sorting by popular orders by the views column descending.
src/app/(public)/buscar/page.tsx
if (sortBy === "popular") {
  qb = qb.order("views", { ascending: false });
} else if (sortBy === "oldest") {
  qb = qb.order("created_at", { ascending: true });
} else {
  qb = qb.order("created_at", { ascending: false });
}
Filters are applied together — you can search for a term within a specific category and sort by popularity simultaneously.

Results display

When a query is present and results are found, the page shows:
  1. A result count summary: e.g., “5 resultados para “elecciones” en Perfil Político”
  2. A responsive 3-column article card grid (ArticleCard component), matching the same card style used on category and tag pages.
src/app/(public)/buscar/page.tsx
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3 sm:gap-6">
  {articles.map((article) => (
    <ArticleCard key={article.slug} {...article} />
  ))}
</div>

Empty state

Two distinct empty states are handled:
ConditionWhat the reader sees
No query enteredThe form is shown; no result count or grid is rendered.
Query entered, zero results”No se encontraron noticias para esta búsqueda.” is shown below the filters.
src/app/(public)/buscar/page.tsx
{articles.length > 0 ? (
  <div className="grid ...">{/* results */}</div>
) : query ? (
  <div className="text-center py-16 text-muted">
    No se encontraron noticias para esta búsqueda.
  </div>
) : null}

Search box in the sidebar

A compact search box also appears in the SidebarPublic component on the home page. It submits to the same /buscar endpoint:
src/components/public/SidebarPublic.tsx
<form action="/buscar" className="flex">
  <input name="q" type="text" placeholder="Buscar noticias..." />
  <button type="submit">Ir</button>
</form>
Because search is server-rendered, results are immediately available without JavaScript and are indexable by search engines.

Build docs developers (and LLMs) love