Relato del desarrollo de un blog full‑stack con Next.js

힘센캥거루
2026년 1월 13일(수정됨)
4
8

Alrededor de un año después de empezar con el desarrollo web, empecé a pensar que quería tener mi propio blog.

Así que estuve dedicado a esto durante unos 6 meses y me puse a crearlo.

Relato del desarrollo de un blog full‑stack con Next.js-1

Para las funcionalidades del front-end creo que basta con tomar como referencia el blog de Kim Do‑hyung de abajo.

A mí tampoco me llevó ni una semana crear un blog usando mdx.

De hecho, para gestionar un blog, con solo el front-end no había grandes problemas.

Durante un tiempo pensé que bastaba con crear mdx y desarrollar solo el front-end, pero no pude renunciar al sueño de un blog full‑stack con el que poder escribir desde cualquier lugar con acceso a la web.

1. Funciones

Las funciones no tienen nada de especial.

Se puede publicar artículos y consultarlos.

Relato del desarrollo de un blog full‑stack con Next.js-2

Al iniciar sesión, la forma del botón de la parte superior derecha cambia.

Y al hacer clic se pueden subir artículos.

En el vídeo de abajo se ve el proceso de escribir y subir un artículo.

Hay un proceso de conversión de imágenes, y todas las imágenes subidas se gestionan en formato avif, que es el más eficiente.

En el caso de YouTube, basta con pegar la URL y se puede insertar como arriba.

La idea de la función de gestión de tablas la tomé de Tistory.

Relato del desarrollo de un blog full‑stack con Next.js-3

Cuando el foco se pone sobre la tabla, aparece en la parte superior una barra de herramientas para añadir o eliminar tablas.

Por supuesto, también es posible el guardado temporal.

Dentro del editor, al pulsar cmd+s o ctrl+s se guarda.

2. Arquitectura

“Arquitectura” suena muy elegante, pero en coreano es simplemente estructura.

La primera petición que entra al servidor la distribuye Caddy como reverse proxy.

Si solo tuviera front‑end, convertiría directamente el mdx y lo enviaría, pero como hice un back‑end, lo conecté con Next.js y Prisma.

Relato del desarrollo de un blog full‑stack con Next.js-4

Como todo el mundo sabe, si metes en el back‑end los datos que vienen del usuario tal cual, te hackean al instante.

Hay que validarlos mediante la API antes de guardarlos.

Relato del desarrollo de un blog full‑stack con Next.js-5

Una vez, con el deseo de que se dejaran muchos comentarios en el blog, dejé la API abierta para que cualquiera pudiera comentar.

Entonces un tipo empezó a lanzar ataques de inyección de consultas a esa API una y otra vez, y acabó habiendo unos 100 comentarios.

También hubo uno que intentó hackear insertando fetch y comandos dentro de una imagen svg.

Puede que en algún lugar de China exista otro “yo” andando tan campante sin que yo lo sepa.

3. Editor

Relato del desarrollo de un blog full‑stack con Next.js-6

Lo que hice con más esmero fue el editor.

El editor lo desarrollé añadiendo varias funciones a Tiptap.

Por eso solo los componentes relacionados con Tiptap superan la decena.

Relato del desarrollo de un blog full‑stack con Next.js-7

En el caso de la inserción de imágenes, lo implementé como se muestra a continuación.

  const editor = useEditor({
    extensions: editorExtensions,
    content,
    onUpdate: ({ editor }) => {
      onChange(editor.getHTML());
    },
    editorProps,
    immediatelyRender: false, 
  });

  const { uploadProgress, uploadImage, clearProgress } = useImageUpload({
    onUploadComplete: (imageUrl, isAnimated) => {
      if (editor) {
        try {
          editor
            .chain()
            .focus()
            .insertContent([
              {
                type: "image",
                attrs: {
                  src: imageUrl,
                  alt: "업로드된 이미지",
                  "data-animated": isAnimated || false,
                },
              },
              {
                type: "paragraph",
                content: [],
              },
            ])
            .run();
        } catch (error) {
          console.error("이미지 삽입 오류:", error);
        }
      }
    },
  });

Para obtener ventajas en cuanto a rendimiento, guardé y cargué el HTML tal cual.

Al guardar desde Tiptap hacia el back‑end añadí varios pasos.

Tras procesar por adelantado distintos elementos como bloques de código, Google Maps, títulos, imágenes, vistas previas de enlaces, etc., guardé por separado content y processedContent.

4. Esquema de back‑end

Recientemente, al implementar un servicio multilingüe, me di cuenta de que cambiar un esquema de back‑end una vez creado es un desastre.

Me vinieron a la mente las palabras del profesor que remarcaba la importancia del esquema.

Si estás pensando incluso en el back‑end del blog, te recomiendo que reflexiones largo y tendido sobre qué servicios ofrecerás.

Al ir añadiendo esto y lo otro, el esquema se volvió demasiado grande, y aunque me da algo de vergüenza, lo hago público.

model Post {
  id               String          @id @default(cuid())
  title            String
  slug             Int             @unique @default(autoincrement())
  excerpt          String
  content          String
  processedContent String?         
  thumbnail        String?
  published        Boolean         @default(false)
  createdAt        DateTime        @default(now())
  updatedAt        DateTime?
  likes            Int             @default(0)
  views            Int             @default(0)
  comments         Comment[]
  likesRows        PostLike[]
  viewDedups       PostViewDedup[]
  notifications    Notification[]
  locales          PostLocale[]
  author           User            @relation(fields: [authorId], references: [id], onDelete: Cascade)
  authorId         String
  category         String
  @@map("posts")
}

5. Conclusiones

Ahora toca responder a la siguiente pregunta.

¿Es necesario llegar hasta el back‑end para crear un blog?

Una vez terminado, me vino a la cabeza: ¿era realmente necesario?

Al final me di cuenta de que WordPress era un camino muchísimo más fácil.

Desde el momento en que implementas el back‑end y las APIs, empiezan a aparecer un montón de cosas en las que pensar.

Durante el reciente incidente de react2shell, recibía ataques cada pocos minutos, y en la terminal aparecían constantemente comandos que nunca había visto, así que pasé varios días duros.

Incluso ahora, cada pocos días paso npm audit para revisar y corregir aspectos de seguridad.

A veces, cuando cambio el esquema de la base de datos y la migración se lía, me entra un sudor frío.

Aun así, mirando atrás, creo que fue positivo haber aprendido muchas cosas al implementar el back‑end y haber conseguido un blog en el que puedo implementar funciones con mis propias manos.

De ahora en adelante, más que añadir funciones al blog, quiero ir realizando otros proyectos para enriquecer mi portafolio.

관련 글

댓글을 불러오는 중...