Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion amplify/data/resource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ const schema = a
owner: a.string().required(),
products: a.hasMany('Product', 'collectionId'),
})
.secondaryIndexes(index => [index('storeId')])
.secondaryIndexes(index => [index('storeId'), index('title')])
.authorization(allow => [
allow.ownerDefinedIn('owner').to(['update', 'delete', 'read', 'create']),
allow.guest().to(['read']),
Expand Down
57 changes: 54 additions & 3 deletions app/[store]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,46 @@
import { Metadata } from 'next'
import { notFound } from 'next/navigation'
import { cache } from 'react'
import { storeRenderer } from '@/lib/store-renderer'

// Forzar renderizado dinámico para acceder a variables de entorno en runtime
export const dynamic = 'force-dynamic'

/**
* Verifica si el path corresponde a un asset estático
*/
function isAssetPath(path: string): boolean {
const assetExtensions = [
'.png',
'.jpg',
'.jpeg',
'.gif',
'.svg',
'.webp',
'.ico',
'.css',
'.js',
'.woff',
'.woff2',
'.ttf',
'.eot',
]
return (
assetExtensions.some(ext => path.toLowerCase().endsWith(ext)) ||
path.startsWith('/assets/') ||
path.startsWith('/_next/') ||
path.includes('/icons/')
)
}

/**
* Función cacheada usando React.cache() que persiste entre generateMetadata y StorePage
* Esta es la forma oficial de Next.js para compartir datos entre estas funciones
*/
const getCachedRenderResult = cache(async (domain: string, path: string) => {
return await storeRenderer.renderPage(domain, path)
})

interface StorePageProps {
params: Promise<{
store: string
Expand All @@ -24,12 +60,18 @@ export default async function StorePage({ params, searchParams }: StorePageProps
const { store } = resolvedParams
const path = resolvedSearchParams.path || '/'

// Validar que no sea una ruta de asset
if (isAssetPath(path)) {
console.warn(`[StorePage] Asset path ${path} should not be handled by page renderer`)
notFound()
}

try {
// Resolver dominio completo (el middleware ya reescribió la URL)
const domain = `${store}.fasttify.com`

// Renderizar página usando el sistema
const result = await storeRenderer.renderPage(domain, path)
// Renderizar página usando el sistema con caché temporal
const result = await getCachedRenderResult(domain, path)

// Retornar HTML renderizado como componente dangerouslySetInnerHTML
// Esto permite SSR completo con SEO optimizado
Expand Down Expand Up @@ -59,10 +101,19 @@ export async function generateMetadata({
const { store } = resolvedParams
const path = resolvedSearchParams.path || '/'

// No generar metadata para assets
if (isAssetPath(path)) {
return {
title: 'Asset',
description: 'Static asset',
}
}

try {
const domain = `${store}.fasttify.com`
const result = await storeRenderer.renderPage(domain, path)

// Usar el cache global para obtener el resultado completo
const result = await getCachedRenderResult(domain, path)
const { metadata } = result

return {
Expand Down
152 changes: 0 additions & 152 deletions app/api/stores/render/route.ts

This file was deleted.

19 changes: 11 additions & 8 deletions lib/store-renderer/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { DynamicPageRenderer, type PageRenderOptions } from './renderers/homepage'
import type { RenderResult } from './types'
import {
DynamicPageRenderer,
type PageRenderOptions,
} from '@/lib/store-renderer/renderers/homepage'
import type { RenderResult } from '@/lib/store-renderer/types'

/**
* Factory principal del sistema de renderizado de tiendas
Expand Down Expand Up @@ -134,11 +137,11 @@ export class StoreRendererFactory {
export const storeRenderer = new StoreRendererFactory()

// Exportar tipos para uso externo
export type { RenderResult } from './types'
export { DynamicPageRenderer } from './renderers/homepage'
export type { RenderResult } from '@/lib/store-renderer/types'
export { DynamicPageRenderer } from '@/lib/store-renderer/renderers/homepage'

// Exportar servicios para uso avanzado
export { domainResolver } from './services/core/domain-resolver'
export { templateLoader } from './services/templates/template-loader'
export { dataFetcher } from './services/fetchers/data-fetcher'
export { liquidEngine } from './liquid/engine'
export { domainResolver } from '@/lib/store-renderer/services/core/domain-resolver'
export { templateLoader } from '@/lib/store-renderer/services/templates/template-loader'
export { dataFetcher } from '@/lib/store-renderer/services/fetchers/data-fetcher'
export { liquidEngine } from '@/lib/store-renderer/liquid/engine'
Loading