Блог

Поля метаданих PDF, пояснено: title, language, author, subject, creator, producer

Розбір шести стандартних полів метаданих PDF, які виставляє gPdf — title, language, author, subject, creator, producer. Для чого кожне, хто читає, поширені помилки і як перевірити вихід.

Компаньйон до Властивості PDF мають показувати ваш бренд, а не чужий інструмент — той допис обґрунтовував, чому варто перейматися метаданими PDF. Цей — операційний посібник: для чого кожне поле в специфікації PDF, хто його читає, поширені помилки і як перевірити, що ваш вихід дійсно відправив те, що ви задумали.

gPdf виставляє шість стандартних полів, які специфікація PDF визначає для метаданих на рівні документа. Вони живуть під settings.metadata в JSON DocumentRequest. Кожне поле опціональне — якщо ви якесь не задасте, gPdf повертається або до default_metadata токена (Enterprise policy feature), або до системного дефолта.

{
  "settings": {
    "metadata": {
      "title":    "...",
      "language": "...",
      "author":   "...",
      "subject":  "...",
      "creator":  "...",
      "producer": "..."
    }
  }
}

Решта допису — один розділ на поле. Кожен розділ слідує одній і тій самій формі: що це за поле, де воно виставляється, поширені помилки, правило великого пальця. Порядок — що заповнити перше → друге → … → останнє.

title — що це за документ

Специфікація PDF описує це як «document title.»

Де виставляється:

  • Рядок заголовка в PDF-переглядачах (Adobe Reader, Preview, Foxit, Chromium PDF viewer — усі його показують).
  • Вкладка браузера, коли PDF відкривається inline (Content-Disposition: inline).
  • Пошукові індекси — Spotlight, Outlook, SharePoint, повнотекстовий індексер Google Drive — усі читають title і важать його високо.

Поширені помилки:

  • Установка title як імені файлу. invoice-20260318.pdf — це ім’я файлу. Title має бути чимось, що читає людина, на кшталт Invoice INV-2026-3401. Ім’я файлу і title — різні справи; ім’я файлу для файлових систем, title — для переглядачів і пошуку.
  • Залишити title порожнім. Переглядачі повертаються до імені файлу. Результат читається як автогенерований і випущений машиною.
  • Додавання бренду в title. Acme Logistics — Invoice INV-2026-3401 захаращує рядок заголовка. Бренд належить до author, а не до title.

Правило великого пальця: title має збігатися з H1 відрендереної сторінки. Якщо верхній рядок вашого шаблону рахунка — «Invoice INV-2026-3401», це й title.

language — для доступності, пошуку й комплаєнсу

language — це BCP-47 мовний тег: en, de, zh-Hans, pt-BR, ar-SA. Задавайте його для кожного документа. Із шести полів він має найконкретніші наслідки для подальших систем і найменшу вартість впровадження — тому він на позиції 2, а не похований нижче.

Де виставляється:

  • Скрін-рідери — JAWS, NVDA, VoiceOver використовують його, щоб вибрати правильний набір фонем. Англомовний скрін-рідер, читаючи PDF із language: "de", вимовлятиме німецькі слова правильно; без тегу він помиляється з просодією.
  • Пошукові системи та індексери — впливає на те, чий локальний стемінг і список стоп-слів застосовується. Рахунок із language: "zh-Hans" індексується китайською сегментацією; відсутній тег часто за замовчуванням стає англійською, і індекс стає непридатним.
  • PDF/A комплаєнс — PDF/A-2a і PDF/A-3a (accessibility profiles) вимагають мовний тег. Без нього валідація veraPDF падає.

Поширені помилки:

  • Залишити незаданим. За замовчуванням ставте «локаль одержувача», а не «дефолт платформи». Більшість діркавих стеків просто не пише поле; результат — скрін-рідери, що неправильно вимовляють, і пошукові індекси, що неправильно стемлять.
  • Використання не-BCP-47 рядка на кшталт "english" або "EN-US". Специфікація PDF очікує теги RFC 5646: en, en-US, de, pt-BR.
  • Хард-кодинг дефолту платформи (напр., завжди "en") незалежно від реальної мови контенту документа. Португальський рахунок із тегом "en" гірший за документ без тегу — він активно вводить індексер в оману.

Правило великого пальця: тег має збігатися з реальною мовою контенту. Для клієнта в Бразилії, що отримує рахунок португальською, задайте "language": "pt-BR", а не "en". Для багатомовних документів виберіть домінуючу мову і використовуйте атрибут Lang на окремих елементах контенту для решти — це фіча tagged-PDF accessibility поза полем language рівня документа.

author — кому належить документ

У специфікації PDF author — це «name of the person or organisation that created the document.» Для бізнес-PDF, що відправляються одержувачам, відповідь майже завжди — організація, але правильна форма дійсно різниться залежно від контексту.

Де виставляється:

  • Діалог Властивостей у кожному PDF-переглядачі, помітно позначений «Author.»
  • DMS / архівні індексери, часто використовується як фільтр.
  • PDF/A XMP metadata stream, де воно потрапляє в довгострокові архіви.

Поширені помилки:

  • "author": "[email protected]" — випадково просочує імейл оператора в кожен PDF, потрапляє в кожен пошуковий індекс, стає довгостроковою проблемою PII.
  • "author": "PDF Generator Service" — внутрішня назва інструмента; нічого не означає для одержувача.
  • ❌ Порожнє — Preview та більшість переглядачів буквально показують «(no author)» в діалозі властивостей, що читається як «нікому не належить.»

Форми, що працюють:

  • "author": "Acme Logistics, Inc." — пряма організація.
  • "author": "Acme Logistics — Billing" — організація + департамент, для документів, що маршрутизуються до конкретного столу.
  • "author": "Bridge Capital Partners — Fund III" — корисно у фінансах/праві, де атрибуція до конкретної сутності.
  • "author": "Maria López, RICS Surveyor" — для одноосібного авторського видання (звіти, оцінки, юридичні висновки), де індивід Є редакційною атрибуцією.

Правило великого пальця: author — це сутність, з якою одержувач має асоціювати документ. У multi-tenant SaaS, де платформа генерує PDF від імені клієнтів, author має бути назвою організації клієнта, а не назвою платформи. (Назва платформи належить до creator — див. нижче.) Для консалтингових / видавничих / юридичних контекстів, де індивіди — це бренд, індивіди ОК.

subject — який це тип документа

subject — це короткий-опис-документа. Переглядачі не виставляють його помітно — більшість користувачів ніколи його не побачать, якщо не відкриють діалог Властивостей. Але системи керування документами, архівні системи та правила маршрутизації пошти/файлів його використовують.

Де виставляється:

  • Діалог властивостей, вторинна позиція.
  • Правила маршрутизації DMS, логіка ковзання архівів.
  • XMP metadata stream (PDF/A).

Поширені помилки:

  • "subject": "Invoice for Acme on 2026-03-18 for $4,532.10" — це опис конкретного екземпляра документа, а не типу. Це належить до title.
  • ❌ Порожнє — позбавляє вас безкоштовного маршрутизаційного гачка для подальших систем.
  • ❌ Непослідовне змішування класів ("Invoice" vs "Invoice/2026-03" vs "Monthly invoice") — DMS-фільтри не можуть бакетити рухому ціль.

Форми, що працюють:

  • "subject": "Invoice"
  • "subject": "Monthly account statement"
  • "subject": "Shipping label — 4×6 thermal"
  • "subject": "Q3 2026 board pack"

Правило великого пальця: правильна гранулярність — клас документа, а не екземпляр документа. DMS із тисячами вхідних PDF може маршрутизувати по subject, якщо ви дасте йому послідовний словник. Виберіть скінченний набір класів для вашої платформи і ніколи не відхиляйтесь — кожен рахунок, який генерує ваша платформа, має мати точно "subject": "Invoice".

creator vs producer — найчастіше плутана пара

Тут більшість команд перестає читати специфікацію PDF і починає вгадувати. Специфікація точна; ці два поля означають різні речі.

  • creator — застосунок, який створив вихідний контент (upstream-система, що вирішила, що має сказати документ).
  • producer — застосунок, який створив байти PDF (рендерний рушій, що перетворив цей контент на PDF-файл).

Для SaaS-біллінг-платформи, що генерує рахунки через JSON-to-PDF API на кшталт gPdf:

  • creator = SaaS-біллінг-платформа з її версією. Це застосунок, що вирішив, що це має бути рахунок для Acme на $4,532.10.
  • producer = рендерер. За замовчуванням це «gPdf.» Але оскільки рендерний шар — інфраструктура, яку обрав SaaS, SaaS може законно задати producer як власну назву платформи — його платформа дійсно, в реальному сенсі, створила байти PDF, делегувавши gPdf як інфраструктурі.
{
  "creator":  "Acme Billing Platform v7.2",
  "producer": "Acme Billing Platform"
}

Де виставляються:

  • Діалог властивостей, обидва позначені.
  • Вивід pdfinfo, поруч.
  • PDF/A XMP stream (обидва поля вимагаються непорожніми в PDF/A).

Поширені помилки:

  • creator задано як user-agent рядок Chromium / Mozilla. Трапляється, коли стек PDF на headless-браузері автоматично передає User-Agent у creator. Це версія браузера, а не система джерела істини. Перевизначте.
  • producer залишено як дефолтну назву рендерера. Більшість команд ніколи це не перевизначає, тому кожен PDF каже «Skia/PDF m120» або «wkhtmltopdf» — див. white-label допис, чому це важливо для B2B.
  • Те саме значення в обох. Прийнятно, але марнотратно — два поля існують саме для того, щоб переглядач міг розрізнити «застосунок-джерело» від «рендерного рушія.» Використовуйте їх.

Правило великого пальця: creator — це назва вашого застосунку з версією (напр., "Acme Billing Platform v7.2"); producer — бренд або назва платформи вашого застосунку без версії (напр., "Acme Billing Platform"). Обидва мають бути значеннями, які впізнає одержувач.

Порожні поля, дефолти на рівні токена, сюрпризи в подальших системах

Три деталі впровадження, які варто знати перед відправкою:

  1. Порожні рядки чи рядки лише з пробілів трактуються як «не надано.» Надсилання "title": "" — те саме, що пропустити title — це не пише порожній рядок у PDF, це йде ланцюжком fallback’у (дефолт токена → системний дефолт). Це причина найчастішого баг-репорту «я задав, не прийнялося.»
  2. Політики токенів можуть викреслювати або задавати дефолти полям метаданих. Multi-tenant SaaS, що використовує gPdf, може задати default_metadata на кожному API-токені, щоб кожен PDF, який цей токен генерує, ніс author і producer клієнта, не довіряючи кожному розробнику задавати їх у кожному запиті. Дефолт на рівні токена — правильний шар enforcement для «кожен PDF Acme має казати Acme.»
  3. Downstream-пайплайни можуть переписати ваші метадані. Інструменти, що постобробляють PDF після того, як gPdf їх повернув — Ghostscript без явних прапорців збереження метаданих, деякі корпоративні DRM-інструменти, деякі «PDF-оптимізатори» — можуть перезаписати Producer власною назвою і скасувати щойно задане вами брендування. Перевіряйте на справжньому продакшен-пайплайні, а не лише на сирій відповіді gPdf.

Перевірте свої метадані

Після того як ви впровадите зміни вище, три швидкі способи перевірити, що PDF справді відправив те, що ви задумали:

Командний рядок (macOS / Linux, потрібен poppler-utils):

$ pdfinfo your-output.pdf | head -10
Title:           Invoice INV-2026-3401
Subject:         Monthly invoice 2026-03
Author:          Acme Logistics, Inc.
Creator:         Acme Billing Platform v7.2
Producer:        Acme Billing Platform
Language:        en

Acrobat / Adobe Reader: Файл → Властивості → вкладка Description. З’являються всі шість полів, із Title показаним у рядку заголовка переглядача вгорі.

macOS Preview: ⌘+I (Get Info). Панель інспектора «PDF» показує ті самі поля.

Якщо якесь поле з’являється порожнім, чистим або з назвою інструмента, яку ви не задавали, поверніться тілом запиту — найчастіша причина в тому, що надсилається "" (порожній рядок), що API трактує як «не надано» і йде ланцюжком fallback’у до дефолтного значення. Друга за поширеністю причина — подальший пайплайн (Ghostscript, DRM, оптимізатор) перезаписує поле після того, як gPdf його повернув; тестуйте на продакшені, а не лише на сирій відповіді рендеру.

Метадані в архівації PDF/A

Якщо ви рендерите для довгострокової архівації з settings.profile: "pdfa-2b" (або -2a, -3a, -3b), метадані перестають бути опціональними і стають несучими:

  • Поле producer не може бути порожнім у PDF/A-сумісному файлі — щонайменше відправляється системний дефолт.
  • language обов’язкове для accessibility-профілів (PDF/A-2a, PDF/A-3a). Без нього валідація veraPDF падає одразу.
  • XMP metadata stream, який PDF/A вимагає, генерується автоматично з шести полів вище; вам не потрібно конструювати його самотужки.
  • title, author, subject, creator, producer і language усі потрапляють у XMP-потік, тож індексер метаданих подальшого архіву (Preservica, Archivematica) може побудувати свій каталог із них без повторного парсингу тіла документа.

Для архівного документа брендовані метадані — це не просто полірування бренду, це частина довговічності артефакту. Німецька митниця, бразильська податкова чи будь-який довгостроковий архів, що відкриє ваш PDF через десять років, побачить те, що було в цих полях у день вашого рендерингу. Задати їх свідомо під час рендерингу — єдиний шанс, який у вас є.

Чого gPdf поки не виставляє

Щоб залишатися чесними щодо сьогоднішньої поверхні: специфікація PDF також визначає Keywords (вільні пошукові терміни) і XMP metadata stream, що підтримує довільні власні пари ключ-значення. gPdf не виставляє жодного з них у поточному API.

Якщо вам потрібно сховати довільні бізнес-дані всередині PDF (UUID замовлення, код складу, версія шаблону), сьогоднішні обхідні шляхи:

  • Задайте subject структурованим коротким рядком, який подальших системи парсять.
  • Тримайте бізнес-дані у власній БД, ключем за іменем файлу чи хешем контенту.
  • Зачекайте — XMP custom fields у roadmap, і коли вони з’являться, це буде правильною відповіддю для прихованого машинно-читаного контексту workflow.

Змішування «брендованих метаданих» (шість стандартних полів, доступні зараз) із «власними бізнес-метаданими» (XMP custom fields, майбутнє) — найпростіший спосіб переобіцяти те, що можливо сьогодні. Варто тримати їх роздільно у власному плануванні.

Повний приклад

SaaS-біллінг-платформа (Acme Billing Platform), що генерує рахунок для німецького клієнта (Müller Versand GmbH), готовий для архівації як PDF/A:

{
  "settings": {
    "profile": "pdfa-3b",
    "metadata": {
      "title":    "Rechnung RE-2026-0412",
      "language": "de",
      "author":   "Müller Versand GmbH",
      "subject":  "Monatsrechnung — März 2026",
      "creator":  "Acme Billing Platform v7.2",
      "producer": "Acme Billing Platform"
    }
  }
}

pdfinfo на отриманому PDF:

$ pdfinfo invoice-2026-0412.pdf | head -10
Title:           Rechnung RE-2026-0412
Subject:         Monatsrechnung — März 2026
Author:          Müller Versand GmbH
Creator:         Acme Billing Platform v7.2
Producer:        Acme Billing Platform
Language:        de

Title німецькою, author як Müller Versand (GmbH-сутність клієнта, одержувач документа), creator як Acme Billing Platform (редакційна система, що вирішила, що покласти на сторінку), producer як бренд Acme Billing Platform, language помічений правильно для німецького скрін-рідера і німецького повнотекстового індексера, який згодом підбере це в DMS Müller. Профіль PDF/A-3b означає, що цей набір метаданих також серіалізується у XMP-потік для довгострокової архівації.

Ніщо у властивостях файлу не називає gPdf, Chromium чи будь-який інструмент, який клієнт не вибирав. Що, власне, і є суть.

Найменше можливе покращення

Якщо ви вже робите POST на /api/v1/pdf/render і ваш поточний виклик не має settings.metadata, найменше покращення — три рядки, додані до JSON, який ви вже надсилаєте:

 {
   "pages": [...],
   "settings": {
+    "metadata": {
+      "author":   "Your customer's organisation",
+      "producer": "Your platform"
+    }
   }
 }

Два поля, один новий ключ. Перевіряється pdfinfo за секунди. Коли ці зміни приживуться, заповніть title, language, subject і creator, коли матимете час.

Де це знаходиться