Blocks vs Components: lo que sobrevive a un rebrand
La division arquitectonica central de ShipAny Next: los blocks desechables leen i18n y conectan contenido, los components duraderos renderizan cualquier cosa que les pases.
Cada plantilla promete "personalizacion facil" y luego te obliga a buscar en doce archivos para cambiar un titular. ShipAny Next evita eso con una regla:
Un archivo que lee traducciones es un block. Un archivo que recibe todo el contenido por props es un component.
Los blocks son desechables
Los blocks viven en src/blocks/ y son secciones de pagina sin configuracion: <Hero />, <Pricing />, <Footer />. Cada uno lee mensajes i18n, arma una configuracion de contenido y se la pasa a un component. Son material demo: cuando empiezas un proyecto real, los borras y escribes los tuyos.
// src/blocks/header.tsx — un block: lee i18n y conecta un component
export async function Header() {
const t = await getTranslations('landing');
const navLinks = [{ href: '/#features', label: t('nav.features') }];
return <SiteHeader navLinks={navLinks} />;
}
Los components son duraderos
Los components viven en src/components/ y nunca leen traducciones. SiteHeader, PricingTable, AppSidebar: todo el contenido llega por props. No conocen el nombre de tu app, tu copy ni tu locale. Exactamente por eso sobreviven a cada rebrand.
Por que importa la division
Cuando haces rebrand o empiezas un proyecto nuevo desde la plantilla:
- Conserva
src/components/*- el chasis. - Reescribe
src/blocks/*- el cableado de contenido. - Reescribe los JSON de traducciones que alimentan los blocks.
Los archivos de pagina se mantienen pequenos: page.tsx es composicion pura, una pila de blocks. Cambiar toda la landing toca blocks y JSON, nunca las primitivas. La division no es cosmetica; convierte la personalizacion en una reescritura de intencion en lugar de una pelea con el diseno de otra persona.