← На главную

Навигация к страницам постов с UUID

Обзор

Обновлена система страниц постов для использования UUID вместо числовых ID. Теперь URL имеют формат /post/{uuid}/.

Пример URL

https://tone.place/post/f9e28984-3e81-462f-b191-7207410c2667/

Структура файлов

app/post/[uid]/
├── page.tsx           # Основная страница поста (обновлена для UUID)
├── error.tsx          # Страница ошибок
└── not-found.tsx      # Страница "не найдено"

API Функции

fetchPostByUid(uid: string): Promise<Post | null>

Загружает пост по UUID.

import { fetchPostByUid } from '@/utils/api'

const post = await fetchPostByUid('f9e28984-3e81-462f-b191-7207410c2667')

getPostUrl(post: Post): string

Генерирует URL для поста (автоматически выбирает UUID или fallback на ID).

import { getPostUrl } from '@/utils/api'

const url = getPostUrl(post) // "/post/f9e28984-3e81-462f-b191-7207410c2667/"

Утилиты UUID

generatePostUrl(postUid: string): string

import { generatePostUrl } from '@/utils/postUtils'

const url = generatePostUrl('f9e28984-3e81-462f-b191-7207410c2667') 
// "/post/f9e28984-3e81-462f-b191-7207410c2667/"

extractPostUidFromParams(uid: string): string | null

import { extractPostUidFromParams } from '@/utils/postUtils'

const uid = extractPostUidFromParams('f9e28984-3e81-462f-b191-7207410c2667')
// "f9e28984-3e81-462f-b191-7207410c2667"

isValidPostUuid(uid: string): boolean

import { isValidPostUuid } from '@/utils/postUtils'

const isValid = isValidPostUuid('f9e28984-3e81-462f-b191-7207410c2667') // true

Добавление навигации к постам

В PostCard компоненте (обновленная версия)

import Link from 'next/link'
import { getPostUrl } from '@/utils/api'

// В компоненте PostCard
const postUrl = getPostUrl(post) // Автоматически выберет UUID или fallback

<Link href={postUrl} className="block hover:bg-gray-50">
  <div className="post-content">
    {/* Содержимое поста */}
  </div>
</Link>

Прямое использование UUID

import { generatePostUrl } from '@/utils/postUtils'

// Если у вас есть UUID поста
<Link href={generatePostUrl(post.uid)} className="text-blue-600">
  Открыть пост →
</Link>

Кнопка "Поделиться" с UUID

import { getPostUrl } from '@/utils/api'

const sharePost = (post: Post) => {
  const postUrl = `${window.location.origin}${getPostUrl(post)}`
  
  if (navigator.share) {
    navigator.share({
      title: 'Пост в ТОН сообществе',
      url: postUrl
    })
  } else {
    navigator.clipboard.writeText(postUrl)
  }
}

Миграция и совместимость

Legacy поддержка

Старые URL формата /post/123@post/ по-прежнему поддерживаются через legacy функции:

// Legacy функции (deprecated)
import { generatePostUrlLegacy, extractPostIdFromSlug } from '@/utils/postUtils'

const legacyUrl = generatePostUrlLegacy(123) // "/post/123@post/"
const legacyId = extractPostIdFromSlug("123@post") // 123

Автоматический выбор URL

Функция getPostUrl(post) автоматически выбирает правильный формат:

  • Если у поста есть uid → использует UUID формат
  • Если нет uid → использует legacy формат с числовым ID

Обновленная структура Post

interface Post {
  id: number
  uid?: string // UUID поста для уникальных URL
  content: string
  // ... остальные поля
}

API Endpoints

Новый endpoint для загрузки по UUID:

GET /api/posts/uid/{uuid}

Fallback на старый endpoint:

GET /api/posts/{id}

SEO оптимизация

UUID страницы автоматически генерируют:

  • Title: {Автор}: "{Превью поста}" - ТОН
  • Description: Первые 160 символов поста
  • Open Graph: URL с UUID для лучшего распространения
  • Twitter Cards: Карточки с UUID

Тестирование

Создайте тестовую ссылку:

<Link href="/post/f9e28984-3e81-462f-b191-7207410c2667/">
  Тестовый пост с UUID
</Link>

Примеры реальных URL

  • /post/f9e28984-3e81-462f-b191-7207410c2667/
  • /post/a1b2c3d4-e5f6-7890-1234-567890abcdef/
  • /post/12345678-9abc-def0-1234-56789abcdef0/

Валидация UUID

Система автоматически валидирует формат UUID (8-4-4-4-12) и показывает 404 для неверных форматов.

Файл: /docs/POST_UUID_NAVIGATION.md