Add SEO data generation and testing for bilingual pages
- Implemented SEO data structures for programmatic tool and collection pages. - Created functions to build FAQs and content sections for SEO pages. - Added tests to ensure at least 50 bilingual SEO pages are generated, no duplicate English slugs, and matching Arabic localized paths. - Verified that both tool and collection SEO inventories are populated adequately.
This commit is contained in:
@@ -17,6 +17,8 @@ interface SEOHeadProps {
|
||||
type?: string;
|
||||
/** Optional JSON-LD objects to inject as structured data */
|
||||
jsonLd?: object | object[];
|
||||
/** Optional explicit language alternates when route-based locale paths are required */
|
||||
alternates?: Array<{ hrefLang: string; href: string; ogLocale?: string }>;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -27,13 +29,13 @@ interface SEOHeadProps {
|
||||
* - Twitter card meta tags
|
||||
* - Optional JSON-LD structured data
|
||||
*/
|
||||
export default function SEOHead({ title, description, keywords, path, type = 'website', jsonLd }: SEOHeadProps) {
|
||||
export default function SEOHead({ title, description, keywords, path, type = 'website', jsonLd, alternates }: SEOHeadProps) {
|
||||
const { i18n } = useTranslation();
|
||||
const origin = getSiteOrigin(typeof window !== 'undefined' ? window.location.origin : '');
|
||||
const canonicalUrl = `${origin}${path}`;
|
||||
const socialImageUrl = buildSocialImageUrl(origin);
|
||||
const fullTitle = `${title} — ${SITE_NAME}`;
|
||||
const languageAlternates = buildLanguageAlternates(origin, path);
|
||||
const languageAlternates = alternates ?? buildLanguageAlternates(origin, path);
|
||||
const currentOgLocale = getOgLocale(i18n.language);
|
||||
|
||||
const schemas = jsonLd ? (Array.isArray(jsonLd) ? jsonLd : [jsonLd]) : [];
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
import seoToolsConfig from '@/config/seo-tools.json';
|
||||
import {
|
||||
PROGRAMMATIC_TOOL_PAGES,
|
||||
SEO_COLLECTION_PAGES,
|
||||
getLocalizedSeoLandingPaths,
|
||||
} from '@/seo/seoData';
|
||||
|
||||
export type SeoLocale = 'en' | 'ar';
|
||||
|
||||
@@ -17,6 +21,11 @@ export interface SeoFaqTemplate {
|
||||
answer: LocalizedText;
|
||||
}
|
||||
|
||||
export interface SeoContentSection {
|
||||
heading: LocalizedText;
|
||||
body: LocalizedText;
|
||||
}
|
||||
|
||||
export interface ProgrammaticToolPage {
|
||||
slug: string;
|
||||
toolSlug: string;
|
||||
@@ -27,6 +36,7 @@ export interface ProgrammaticToolPage {
|
||||
descriptionTemplate: LocalizedText;
|
||||
faqTemplates: SeoFaqTemplate[];
|
||||
relatedCollectionSlugs: string[];
|
||||
contentSections?: SeoContentSection[];
|
||||
}
|
||||
|
||||
export interface SeoCollectionPage {
|
||||
@@ -39,18 +49,9 @@ export interface SeoCollectionPage {
|
||||
targetToolSlugs: string[];
|
||||
faqTemplates: SeoFaqTemplate[];
|
||||
relatedCollectionSlugs: string[];
|
||||
contentSections?: SeoContentSection[];
|
||||
}
|
||||
|
||||
interface SeoToolsConfig {
|
||||
toolPages: ProgrammaticToolPage[];
|
||||
collectionPages: SeoCollectionPage[];
|
||||
}
|
||||
|
||||
const config = seoToolsConfig as SeoToolsConfig;
|
||||
|
||||
export const PROGRAMMATIC_TOOL_PAGES = config.toolPages;
|
||||
export const SEO_COLLECTION_PAGES = config.collectionPages;
|
||||
|
||||
export function normalizeSeoLocale(language: string): SeoLocale {
|
||||
return language.toLowerCase().startsWith('ar') ? 'ar' : 'en';
|
||||
}
|
||||
@@ -85,4 +86,8 @@ export function getAllCollectionSeoPaths(): string[] {
|
||||
|
||||
export function getAllSeoLandingPaths(): string[] {
|
||||
return [...getAllProgrammaticSeoPaths(), ...getAllCollectionSeoPaths()];
|
||||
}
|
||||
|
||||
export function getAllLocalizedSeoLandingPaths(): string[] {
|
||||
return [...getLocalizedSeoLandingPaths('en'), ...getLocalizedSeoLandingPaths('ar')];
|
||||
}
|
||||
@@ -64,9 +64,7 @@ export default function SeoCollectionPage({ slug }: SeoCollectionPageProps) {
|
||||
const description = interpolateTemplate(getLocalizedText(page.descriptionTemplate, locale), tokens);
|
||||
const intro = interpolateTemplate(getLocalizedText(page.introTemplate, locale), tokens);
|
||||
const keywords = [focusKeyword, ...getLocalizedTextList(page.supportingKeywords, locale)].join(', ');
|
||||
const path = `/${page.slug}`;
|
||||
const siteOrigin = getSiteOrigin(typeof window !== 'undefined' ? window.location.origin : '');
|
||||
const url = `${siteOrigin}${path}`;
|
||||
const faqItems = page.faqTemplates.map((item) => ({
|
||||
question: getLocalizedText(item.question, locale),
|
||||
answer: getLocalizedText(item.answer, locale),
|
||||
@@ -74,6 +72,13 @@ export default function SeoCollectionPage({ slug }: SeoCollectionPageProps) {
|
||||
const relatedCollections = page.relatedCollectionSlugs
|
||||
.map((collectionSlug) => getSeoCollectionPage(collectionSlug))
|
||||
.filter((entry): entry is NonNullable<typeof entry> => Boolean(entry));
|
||||
const contentSections = page.contentSections ?? [];
|
||||
const path = locale === 'ar' ? `/ar/${page.slug}` : `/${page.slug}`;
|
||||
const url = `${siteOrigin}${path}`;
|
||||
const alternates = [
|
||||
{ hrefLang: 'en', href: `${siteOrigin}/${page.slug}`, ogLocale: 'en_US' },
|
||||
{ hrefLang: 'ar', href: `${siteOrigin}/ar/${page.slug}`, ogLocale: 'ar_SA' },
|
||||
];
|
||||
|
||||
const jsonLd = [
|
||||
generateWebPage({
|
||||
@@ -91,7 +96,7 @@ export default function SeoCollectionPage({ slug }: SeoCollectionPageProps) {
|
||||
|
||||
return (
|
||||
<>
|
||||
<SEOHead title={title} description={description} path={path} keywords={keywords} jsonLd={jsonLd} />
|
||||
<SEOHead title={title} description={description} path={path} keywords={keywords} jsonLd={jsonLd} alternates={alternates} />
|
||||
|
||||
<div className="mx-auto max-w-6xl space-y-10">
|
||||
<section className="rounded-[2rem] border border-slate-200 bg-white p-8 shadow-sm dark:border-slate-700 dark:bg-slate-900/70 sm:p-10">
|
||||
@@ -166,6 +171,21 @@ export default function SeoCollectionPage({ slug }: SeoCollectionPageProps) {
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
{contentSections.length > 0 ? (
|
||||
<section className="grid gap-6 lg:grid-cols-2">
|
||||
{contentSections.map((section) => (
|
||||
<article key={section.heading.en} className="rounded-2xl border border-slate-200 bg-white p-7 shadow-sm dark:border-slate-700 dark:bg-slate-900/70">
|
||||
<h2 className="text-2xl font-semibold text-slate-900 dark:text-white">
|
||||
{getLocalizedText(section.heading, locale)}
|
||||
</h2>
|
||||
<p className="mt-4 leading-8 text-slate-700 dark:text-slate-300">
|
||||
{getLocalizedText(section.body, locale)}
|
||||
</p>
|
||||
</article>
|
||||
))}
|
||||
</section>
|
||||
) : null}
|
||||
|
||||
<section className="rounded-2xl border border-slate-200 bg-white p-7 shadow-sm dark:border-slate-700 dark:bg-slate-900/70">
|
||||
<h2 className="text-2xl font-semibold text-slate-900 dark:text-white">
|
||||
{copy.relatedHeading}
|
||||
@@ -180,12 +200,12 @@ export default function SeoCollectionPage({ slug }: SeoCollectionPageProps) {
|
||||
return (
|
||||
<Link
|
||||
key={collection.slug}
|
||||
to={`/${collection.slug}`}
|
||||
to={locale === 'ar' ? `/ar/${collection.slug}` : `/${collection.slug}`}
|
||||
className="rounded-2xl border border-slate-200 p-5 transition-colors hover:border-primary-300 hover:bg-slate-50 dark:border-slate-700 dark:hover:border-primary-600 dark:hover:bg-slate-800"
|
||||
>
|
||||
<div className="flex items-center gap-2 text-primary-600 dark:text-primary-400">
|
||||
<Link2 className="h-4 w-4" />
|
||||
<span className="text-sm font-medium">/{collection.slug}</span>
|
||||
<span className="text-sm font-medium">{locale === 'ar' ? `/ar/${collection.slug}` : `/${collection.slug}`}</span>
|
||||
</div>
|
||||
<p className="mt-3 font-semibold text-slate-900 dark:text-white">{collectionTitle}</p>
|
||||
</Link>
|
||||
|
||||
@@ -98,6 +98,7 @@ export default function SeoPage({ slug }: SeoPageProps) {
|
||||
const relatedCollections = page.relatedCollectionSlugs
|
||||
.map((collectionSlug) => getSeoCollectionPage(collectionSlug))
|
||||
.filter((entry): entry is NonNullable<typeof entry> => Boolean(entry));
|
||||
const contentSections = page.contentSections ?? [];
|
||||
|
||||
const introBody = `${toolDescription} ${description}`;
|
||||
const workflowBody = `${t(`seo.${tool.i18nKey}.whatItDoes`)} ${t(`tools.${tool.i18nKey}.shortDesc`)}`;
|
||||
@@ -108,6 +109,10 @@ export default function SeoPage({ slug }: SeoPageProps) {
|
||||
return relatedTool ? t(`tools.${relatedTool.i18nKey}.title`) : relatedSlug;
|
||||
});
|
||||
const localizedCollectionPath = (collectionSlug: string) => (locale === 'ar' ? `/ar/${collectionSlug}` : `/${collectionSlug}`);
|
||||
const alternates = [
|
||||
{ hrefLang: 'en', href: `${siteOrigin}/${page.slug}`, ogLocale: 'en_US' },
|
||||
{ hrefLang: 'ar', href: `${siteOrigin}/ar/${page.slug}`, ogLocale: 'ar_SA' },
|
||||
];
|
||||
|
||||
const jsonLd = [
|
||||
generateWebPage({
|
||||
@@ -137,7 +142,7 @@ export default function SeoPage({ slug }: SeoPageProps) {
|
||||
|
||||
return (
|
||||
<>
|
||||
<SEOHead title={title} description={description} path={path} keywords={keywords} jsonLd={jsonLd} />
|
||||
<SEOHead title={title} description={description} path={path} keywords={keywords} jsonLd={jsonLd} alternates={alternates} />
|
||||
|
||||
<div className="mx-auto max-w-6xl space-y-12">
|
||||
<section className="rounded-[2rem] border border-slate-200 bg-white p-8 shadow-sm dark:border-slate-700 dark:bg-slate-900/70 sm:p-10">
|
||||
@@ -230,6 +235,21 @@ export default function SeoPage({ slug }: SeoPageProps) {
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{contentSections.length > 0 ? (
|
||||
<section className="grid gap-6 lg:grid-cols-2">
|
||||
{contentSections.map((section) => (
|
||||
<article key={section.heading.en} className="rounded-2xl border border-slate-200 bg-white p-7 shadow-sm dark:border-slate-700 dark:bg-slate-900/70">
|
||||
<h2 className="text-2xl font-semibold text-slate-900 dark:text-white">
|
||||
{getLocalizedText(section.heading, locale)}
|
||||
</h2>
|
||||
<p className="mt-4 leading-8 text-slate-700 dark:text-slate-300">
|
||||
{getLocalizedText(section.body, locale)}
|
||||
</p>
|
||||
</article>
|
||||
))}
|
||||
</section>
|
||||
) : null}
|
||||
|
||||
<section className="rounded-2xl border border-slate-200 bg-white p-7 shadow-sm dark:border-slate-700 dark:bg-slate-900/70">
|
||||
<h2 className="text-2xl font-semibold text-slate-900 dark:text-white">
|
||||
{copy.relatedHeading}
|
||||
|
||||
901
frontend/src/seo/seoData.json
Normal file
901
frontend/src/seo/seoData.json
Normal file
@@ -0,0 +1,901 @@
|
||||
{
|
||||
"toolPageSeeds": [
|
||||
{
|
||||
"slug": "pdf-to-word",
|
||||
"toolSlug": "pdf-to-word",
|
||||
"category": "PDF",
|
||||
"focusKeyword": { "en": "pdf to word", "ar": "تحويل PDF إلى Word" },
|
||||
"supportingKeywords": {
|
||||
"en": ["pdf to docx", "convert pdf to word online", "editable word from pdf"],
|
||||
"ar": ["تحويل pdf الى word", "تحويل pdf إلى docx", "تحويل ملف pdf إلى وورد"]
|
||||
},
|
||||
"benefit": {
|
||||
"en": "Turn fixed PDF pages into editable Word files without rebuilding the document from scratch.",
|
||||
"ar": "حوّل صفحات PDF الثابتة إلى ملفات Word قابلة للتحرير بدون إعادة بناء المستند من البداية."
|
||||
},
|
||||
"useCase": {
|
||||
"en": "Best for contracts, resumes, reports, and client revisions.",
|
||||
"ar": "مناسب للعقود والسير الذاتية والتقارير وتعديلات العملاء."
|
||||
},
|
||||
"relatedCollectionSlugs": ["best-pdf-tools", "convert-files-online"]
|
||||
},
|
||||
{
|
||||
"slug": "word-to-pdf",
|
||||
"toolSlug": "word-to-pdf",
|
||||
"category": "Convert",
|
||||
"focusKeyword": { "en": "word to pdf", "ar": "تحويل Word إلى PDF" },
|
||||
"supportingKeywords": {
|
||||
"en": ["docx to pdf", "convert word to pdf online", "save word as pdf"],
|
||||
"ar": ["تحويل وورد إلى pdf", "docx إلى pdf", "تحويل ملف word إلى pdf"]
|
||||
},
|
||||
"benefit": {
|
||||
"en": "Create clean, shareable PDFs from Word files while preserving layout for print or approvals.",
|
||||
"ar": "أنشئ ملفات PDF نظيفة وقابلة للمشاركة من ملفات Word مع الحفاظ على التنسيق للطباعة أو الاعتماد."
|
||||
},
|
||||
"useCase": {
|
||||
"en": "Useful for proposals, handouts, policies, and invoices.",
|
||||
"ar": "مفيد للعروض والمطبوعات والسياسات والفواتير."
|
||||
},
|
||||
"relatedCollectionSlugs": ["pdf-converter-tools", "office-to-pdf-tools"]
|
||||
},
|
||||
{
|
||||
"slug": "compress-pdf-online",
|
||||
"toolSlug": "compress-pdf",
|
||||
"category": "PDF",
|
||||
"focusKeyword": { "en": "compress pdf online", "ar": "ضغط PDF أونلاين" },
|
||||
"supportingKeywords": {
|
||||
"en": ["reduce pdf size", "make pdf smaller", "shrink pdf online"],
|
||||
"ar": ["ضغط ملف pdf", "تقليل حجم pdf", "تصغير ملف pdf"]
|
||||
},
|
||||
"benefit": {
|
||||
"en": "Reduce large PDFs so they are easier to email, upload, archive, and open on mobile devices.",
|
||||
"ar": "قلّل حجم ملفات PDF الكبيرة لتصبح أسهل في الإرسال والرفع والأرشفة والفتح على الجوال."
|
||||
},
|
||||
"useCase": {
|
||||
"en": "Ideal for email attachments, portals with size limits, and document archives.",
|
||||
"ar": "مثالي لمرفقات البريد الإلكتروني والبوابات ذات حدود الحجم وأرشيف المستندات."
|
||||
},
|
||||
"relatedCollectionSlugs": ["free-pdf-tools-online", "best-pdf-tools"]
|
||||
},
|
||||
{
|
||||
"slug": "convert-jpg-to-pdf",
|
||||
"toolSlug": "images-to-pdf",
|
||||
"category": "PDF",
|
||||
"focusKeyword": { "en": "convert jpg to pdf", "ar": "تحويل JPG إلى PDF" },
|
||||
"supportingKeywords": {
|
||||
"en": ["jpg to pdf online", "photo to pdf", "combine jpg into pdf"],
|
||||
"ar": ["تحويل jpg إلى pdf", "صورة إلى pdf", "دمج صور jpg في pdf"]
|
||||
},
|
||||
"benefit": {
|
||||
"en": "Turn one or more JPG images into a single PDF document that is easier to share and print.",
|
||||
"ar": "حوّل صورة JPG واحدة أو عدة صور إلى ملف PDF واحد أسهل في المشاركة والطباعة."
|
||||
},
|
||||
"useCase": {
|
||||
"en": "Common for receipts, scanned pages, IDs, and application uploads.",
|
||||
"ar": "شائع للإيصالات والصفحات الممسوحة ضوئياً وبطاقات الهوية وملفات التقديم."
|
||||
},
|
||||
"relatedCollectionSlugs": ["image-to-pdf-tools", "convert-files-online"]
|
||||
},
|
||||
{
|
||||
"slug": "merge-pdf-files",
|
||||
"toolSlug": "merge-pdf",
|
||||
"category": "PDF",
|
||||
"focusKeyword": { "en": "merge pdf files", "ar": "دمج ملفات PDF" },
|
||||
"supportingKeywords": {
|
||||
"en": ["combine pdf files", "join pdf online", "merge pdf documents"],
|
||||
"ar": ["دمج ملفات pdf", "دمج pdf", "جمع ملفات pdf"]
|
||||
},
|
||||
"benefit": {
|
||||
"en": "Combine multiple PDFs into one ordered file without changing the original page quality.",
|
||||
"ar": "ادمج عدة ملفات PDF في ملف واحد مرتب بدون التأثير على جودة الصفحات الأصلية."
|
||||
},
|
||||
"useCase": {
|
||||
"en": "Useful for proposals, legal packets, onboarding files, and reporting bundles.",
|
||||
"ar": "مفيد للعروض والملفات القانونية وحزم onboarding وتجميع التقارير."
|
||||
},
|
||||
"relatedCollectionSlugs": ["best-pdf-tools", "secure-pdf-tools"]
|
||||
},
|
||||
{
|
||||
"slug": "remove-pdf-password",
|
||||
"toolSlug": "unlock-pdf",
|
||||
"category": "PDF",
|
||||
"focusKeyword": { "en": "remove pdf password", "ar": "إزالة كلمة مرور PDF" },
|
||||
"supportingKeywords": {
|
||||
"en": ["unlock pdf", "remove pdf protection", "open locked pdf"],
|
||||
"ar": ["فتح قفل pdf", "إزالة حماية pdf", "إلغاء كلمة سر pdf"]
|
||||
},
|
||||
"benefit": {
|
||||
"en": "Remove protection from PDFs you already have permission to open so editing and sharing are faster.",
|
||||
"ar": "أزل الحماية من ملفات PDF التي لديك إذن بفتحها بالفعل حتى تصبح عملية التعديل والمشاركة أسرع."
|
||||
},
|
||||
"useCase": {
|
||||
"en": "Helpful when teams need to print, review, merge, or archive secured files.",
|
||||
"ar": "مفيد عندما تحتاج الفرق إلى طباعة الملفات المؤمنة أو مراجعتها أو دمجها أو أرشفتها."
|
||||
},
|
||||
"relatedCollectionSlugs": ["secure-pdf-tools", "free-pdf-tools-online"]
|
||||
},
|
||||
{
|
||||
"slug": "pdf-to-word-editable",
|
||||
"toolSlug": "pdf-to-word",
|
||||
"category": "PDF",
|
||||
"focusKeyword": { "en": "pdf to word editable", "ar": "تحويل PDF إلى Word قابل للتعديل" },
|
||||
"supportingKeywords": {
|
||||
"en": ["editable pdf to word", "make pdf editable in word", "pdf to editable docx"],
|
||||
"ar": ["pdf إلى word قابل للتعديل", "تحويل pdf قابل للتحرير", "ملف وورد قابل للتعديل من pdf"]
|
||||
},
|
||||
"benefit": {
|
||||
"en": "Create a Word version that can be revised quickly instead of retyping content from a static PDF.",
|
||||
"ar": "أنشئ نسخة Word قابلة للتعديل بسرعة بدلاً من إعادة كتابة محتوى PDF ثابت يدوياً."
|
||||
},
|
||||
"useCase": {
|
||||
"en": "Best for editable forms, vendor documents, and reused templates.",
|
||||
"ar": "مناسب للنماذج القابلة للتعديل ووثائق الموردين والقوالب المعاد استخدامها."
|
||||
},
|
||||
"relatedCollectionSlugs": ["pdf-converter-tools", "scanned-document-tools"]
|
||||
},
|
||||
{
|
||||
"slug": "convert-pdf-to-text",
|
||||
"toolSlug": "ocr",
|
||||
"category": "AI",
|
||||
"focusKeyword": { "en": "convert pdf to text", "ar": "تحويل PDF إلى نص" },
|
||||
"supportingKeywords": {
|
||||
"en": ["pdf to text online", "extract text from pdf", "pdf text extraction"],
|
||||
"ar": ["تحويل pdf إلى نص", "استخراج النص من pdf", "قراءة نص pdf"]
|
||||
},
|
||||
"benefit": {
|
||||
"en": "Extract readable text from scanned or image-based PDFs so content becomes searchable and reusable.",
|
||||
"ar": "استخرج نصاً قابلاً للقراءة من ملفات PDF الممسوحة ضوئياً أو المعتمدة على الصور ليصبح المحتوى قابلاً للبحث وإعادة الاستخدام."
|
||||
},
|
||||
"useCase": {
|
||||
"en": "Useful for reports, scanned forms, research material, and document indexing.",
|
||||
"ar": "مفيد للتقارير والنماذج الممسوحة ضوئياً ومواد البحث وفهرسة المستندات."
|
||||
},
|
||||
"relatedCollectionSlugs": ["ai-document-tools", "scanned-document-tools"]
|
||||
},
|
||||
{
|
||||
"slug": "split-pdf-online",
|
||||
"toolSlug": "split-pdf",
|
||||
"category": "PDF",
|
||||
"focusKeyword": { "en": "split pdf online", "ar": "تقسيم PDF أونلاين" },
|
||||
"supportingKeywords": {
|
||||
"en": ["split pdf pages", "divide pdf", "separate pdf pages"],
|
||||
"ar": ["تقسيم ملف pdf", "فصل صفحات pdf", "تجزئة pdf"]
|
||||
},
|
||||
"benefit": {
|
||||
"en": "Break large PDFs into smaller parts or isolate the exact pages you need for the next workflow.",
|
||||
"ar": "قسّم ملفات PDF الكبيرة إلى أجزاء أصغر أو اعزل الصفحات التي تحتاجها فقط للمسار التالي."
|
||||
},
|
||||
"useCase": {
|
||||
"en": "Helpful for chapter sharing, legal exhibits, and trimmed uploads.",
|
||||
"ar": "مفيد لمشاركة الفصول والمرفقات القانونية ورفع ملفات مختصرة."
|
||||
},
|
||||
"relatedCollectionSlugs": ["best-pdf-tools", "free-pdf-tools-online"]
|
||||
},
|
||||
{
|
||||
"slug": "jpg-to-pdf",
|
||||
"toolSlug": "images-to-pdf",
|
||||
"category": "PDF",
|
||||
"focusKeyword": { "en": "jpg to pdf", "ar": "تحويل JPG إلى PDF" },
|
||||
"supportingKeywords": {
|
||||
"en": ["image to pdf", "jpg file to pdf", "convert jpg file to pdf"],
|
||||
"ar": ["jpg إلى pdf", "تحويل صورة jpg إلى pdf", "تحويل الصور الى pdf"]
|
||||
},
|
||||
"benefit": {
|
||||
"en": "Convert JPG files into a clean PDF format that works across devices and office workflows.",
|
||||
"ar": "حوّل ملفات JPG إلى صيغة PDF نظيفة تعمل عبر الأجهزة ومسارات العمل المكتبية."
|
||||
},
|
||||
"useCase": {
|
||||
"en": "Good for homework scans, receipts, forms, and proofs of identity.",
|
||||
"ar": "جيد للواجبات الممسوحة ضوئياً والإيصالات والنماذج وإثباتات الهوية."
|
||||
},
|
||||
"relatedCollectionSlugs": ["image-to-pdf-tools", "arabic-pdf-tools"]
|
||||
},
|
||||
{
|
||||
"slug": "png-to-pdf",
|
||||
"toolSlug": "images-to-pdf",
|
||||
"category": "PDF",
|
||||
"focusKeyword": { "en": "png to pdf", "ar": "تحويل PNG إلى PDF" },
|
||||
"supportingKeywords": {
|
||||
"en": ["convert png to pdf", "png file to pdf", "png image pdf"],
|
||||
"ar": ["تحويل png إلى pdf", "ملف png إلى pdf", "صورة png إلى pdf"]
|
||||
},
|
||||
"benefit": {
|
||||
"en": "Package PNG images into PDF while keeping diagrams, screenshots, and transparency-heavy content organized.",
|
||||
"ar": "حوّل صور PNG إلى PDF مع إبقاء المخططات ولقطات الشاشة والمحتوى المنظم بصورة مرتبة."
|
||||
},
|
||||
"useCase": {
|
||||
"en": "Useful for mockups, screenshots, annotated notes, and design exports.",
|
||||
"ar": "مفيد للنماذج الأولية ولقطات الشاشة والملاحظات المشروحة وتصدير التصاميم."
|
||||
},
|
||||
"relatedCollectionSlugs": ["image-to-pdf-tools", "online-image-tools"]
|
||||
},
|
||||
{
|
||||
"slug": "images-to-pdf-online",
|
||||
"toolSlug": "images-to-pdf",
|
||||
"category": "PDF",
|
||||
"focusKeyword": { "en": "images to pdf online", "ar": "تحويل الصور إلى PDF أونلاين" },
|
||||
"supportingKeywords": {
|
||||
"en": ["combine images into pdf", "multiple images to pdf", "photos to pdf online"],
|
||||
"ar": ["تحويل الصور الى pdf", "دمج الصور في pdf", "عدة صور إلى pdf"]
|
||||
},
|
||||
"benefit": {
|
||||
"en": "Combine multiple images into one portable PDF instead of sending several separate files.",
|
||||
"ar": "ادمج عدة صور في ملف PDF واحد قابل للنقل بدلاً من إرسال عدة ملفات منفصلة."
|
||||
},
|
||||
"useCase": {
|
||||
"en": "Useful for case files, property photos, receipts, and scanned homework.",
|
||||
"ar": "مفيد لملفات القضايا وصور العقارات والإيصالات والواجبات الممسوحة ضوئياً."
|
||||
},
|
||||
"relatedCollectionSlugs": ["image-to-pdf-tools", "free-pdf-tools-online"]
|
||||
},
|
||||
{
|
||||
"slug": "pdf-to-jpg",
|
||||
"toolSlug": "pdf-to-images",
|
||||
"category": "PDF",
|
||||
"focusKeyword": { "en": "pdf to jpg", "ar": "تحويل PDF إلى JPG" },
|
||||
"supportingKeywords": {
|
||||
"en": ["convert pdf to jpg", "pdf page to image", "save pdf as jpg"],
|
||||
"ar": ["تحويل pdf إلى jpg", "صفحات pdf إلى صور", "حفظ pdf كـ jpg"]
|
||||
},
|
||||
"benefit": {
|
||||
"en": "Turn PDF pages into JPG images for quick previews, sharing in chat apps, or slide decks.",
|
||||
"ar": "حوّل صفحات PDF إلى صور JPG للمعاينة السريعة أو المشاركة في تطبيقات المحادثة أو العروض."
|
||||
},
|
||||
"useCase": {
|
||||
"en": "Best for presentations, social posts, proof snapshots, and lightweight sharing.",
|
||||
"ar": "مناسب للعروض والمنشورات الاجتماعية ولقطات الإثبات والمشاركة الخفيفة."
|
||||
},
|
||||
"relatedCollectionSlugs": ["pdf-converter-tools", "convert-files-online"]
|
||||
},
|
||||
{
|
||||
"slug": "pdf-to-png",
|
||||
"toolSlug": "pdf-to-images",
|
||||
"category": "PDF",
|
||||
"focusKeyword": { "en": "pdf to png", "ar": "تحويل PDF إلى PNG" },
|
||||
"supportingKeywords": {
|
||||
"en": ["convert pdf to png", "pdf page to png", "high quality pdf image"],
|
||||
"ar": ["تحويل pdf إلى png", "صفحة pdf إلى png", "صورة عالية الجودة من pdf"]
|
||||
},
|
||||
"benefit": {
|
||||
"en": "Export crisp PNG images from PDF pages when clarity matters for screenshots, interfaces, or graphics.",
|
||||
"ar": "صدّر صور PNG واضحة من صفحات PDF عندما تكون الدقة مهمة لواجهات الاستخدام أو الرسومات أو لقطات الشاشة."
|
||||
},
|
||||
"useCase": {
|
||||
"en": "Good for annotated visuals, UI reviews, graphics handoff, and transparent workflows.",
|
||||
"ar": "جيد للمرئيات المشروحة ومراجعات الواجهات وتسليم الرسومات ومسارات العمل التي تحتاج وضوحاً أعلى."
|
||||
},
|
||||
"relatedCollectionSlugs": ["pdf-converter-tools", "online-image-tools"]
|
||||
},
|
||||
{
|
||||
"slug": "compress-pdf-for-email",
|
||||
"toolSlug": "compress-pdf",
|
||||
"category": "PDF",
|
||||
"focusKeyword": { "en": "compress pdf for email", "ar": "ضغط PDF للإيميل" },
|
||||
"supportingKeywords": {
|
||||
"en": ["email pdf size limit", "reduce pdf for attachment", "small pdf for email"],
|
||||
"ar": ["ضغط pdf للبريد", "تقليل حجم pdf للإرسال", "ملف pdf صغير للإيميل"]
|
||||
},
|
||||
"benefit": {
|
||||
"en": "Shrink PDFs to meet common attachment limits without making documents unreadable.",
|
||||
"ar": "قلّل حجم ملفات PDF لتوافق حدود المرفقات الشائعة بدون أن تصبح المستندات غير قابلة للقراءة."
|
||||
},
|
||||
"useCase": {
|
||||
"en": "Useful for HR forms, vendor documents, client approvals, and support tickets.",
|
||||
"ar": "مفيد لنماذج الموارد البشرية ووثائق الموردين وموافقات العملاء وتذاكر الدعم."
|
||||
},
|
||||
"relatedCollectionSlugs": ["free-pdf-tools-online", "secure-pdf-tools"]
|
||||
},
|
||||
{
|
||||
"slug": "compress-scanned-pdf",
|
||||
"toolSlug": "compress-pdf",
|
||||
"category": "PDF",
|
||||
"focusKeyword": { "en": "compress scanned pdf", "ar": "ضغط PDF ممسوح ضوئياً" },
|
||||
"supportingKeywords": {
|
||||
"en": ["reduce scanned pdf size", "scan pdf compressor", "shrink image-based pdf"],
|
||||
"ar": ["ضغط ملف pdf ممسوح", "تقليل حجم pdf ممسوح", "ضغط pdf صور"]
|
||||
},
|
||||
"benefit": {
|
||||
"en": "Cut the size of image-heavy scanned PDFs so they can be uploaded and shared more easily.",
|
||||
"ar": "خفّض حجم ملفات PDF الممسوحة ضوئياً والغنية بالصور حتى يمكن رفعها ومشاركتها بسهولة أكبر."
|
||||
},
|
||||
"useCase": {
|
||||
"en": "Helpful for archive scans, office paperwork, and portal submissions.",
|
||||
"ar": "مفيد للأرشفة الممسوحة ضوئياً والأوراق المكتبية والرفع إلى البوابات."
|
||||
},
|
||||
"relatedCollectionSlugs": ["scanned-document-tools", "best-pdf-tools"]
|
||||
},
|
||||
{
|
||||
"slug": "merge-pdf-online-free",
|
||||
"toolSlug": "merge-pdf",
|
||||
"category": "PDF",
|
||||
"focusKeyword": { "en": "merge pdf online free", "ar": "دمج PDF أونلاين مجاناً" },
|
||||
"supportingKeywords": {
|
||||
"en": ["free merge pdf", "combine pdf online free", "join pdf files free"],
|
||||
"ar": ["دمج pdf مجاناً", "جمع pdf أونلاين", "دمج ملفات pdf مجانا"]
|
||||
},
|
||||
"benefit": {
|
||||
"en": "Assemble multiple PDFs into one document in the browser without extra desktop software.",
|
||||
"ar": "اجمع عدة ملفات PDF في مستند واحد داخل المتصفح بدون برامج سطح مكتب إضافية."
|
||||
},
|
||||
"useCase": {
|
||||
"en": "Common for bid packs, onboarding bundles, and document handoffs.",
|
||||
"ar": "شائع لحزم العطاءات وملفات onboarding وتسليم المستندات."
|
||||
},
|
||||
"relatedCollectionSlugs": ["free-pdf-tools-online", "best-pdf-tools"]
|
||||
},
|
||||
{
|
||||
"slug": "combine-pdf-files",
|
||||
"toolSlug": "merge-pdf",
|
||||
"category": "PDF",
|
||||
"focusKeyword": { "en": "combine pdf files", "ar": "جمع ملفات PDF" },
|
||||
"supportingKeywords": {
|
||||
"en": ["combine multiple pdf files", "join pdf documents", "put pdf files together"],
|
||||
"ar": ["جمع ملفات pdf", "تجميع مستندات pdf", "ضم ملفات pdf"]
|
||||
},
|
||||
"benefit": {
|
||||
"en": "Put related PDF files together so teams review one document instead of many separate attachments.",
|
||||
"ar": "اجمع ملفات PDF المرتبطة معاً حتى تراجع الفرق مستنداً واحداً بدلاً من عدة مرفقات منفصلة."
|
||||
},
|
||||
"useCase": {
|
||||
"en": "Useful for applications, case files, board packs, and proposal sets.",
|
||||
"ar": "مفيد لطلبات التقديم وملفات القضايا وحزم الاجتماعات ومجموعات العروض."
|
||||
},
|
||||
"relatedCollectionSlugs": ["best-pdf-tools", "office-to-pdf-tools"]
|
||||
},
|
||||
{
|
||||
"slug": "extract-pages-from-pdf",
|
||||
"toolSlug": "extract-pages",
|
||||
"category": "PDF",
|
||||
"focusKeyword": { "en": "extract pages from pdf", "ar": "استخراج صفحات من PDF" },
|
||||
"supportingKeywords": {
|
||||
"en": ["select pages from pdf", "save selected pdf pages", "pdf page extractor"],
|
||||
"ar": ["استخراج صفحات من pdf", "حفظ صفحات pdf محددة", "أداة استخراج صفحات pdf"]
|
||||
},
|
||||
"benefit": {
|
||||
"en": "Keep only the pages you need from a larger PDF before sending or reusing the document.",
|
||||
"ar": "احتفظ فقط بالصفحات التي تحتاجها من ملف PDF أكبر قبل إرسال المستند أو إعادة استخدامه."
|
||||
},
|
||||
"useCase": {
|
||||
"en": "Helpful for exhibits, chapter handoffs, and trimmed submissions.",
|
||||
"ar": "مفيد للملاحق والفصول المقتطعة وعمليات الرفع المختصرة."
|
||||
},
|
||||
"relatedCollectionSlugs": ["best-pdf-tools", "secure-pdf-tools"]
|
||||
},
|
||||
{
|
||||
"slug": "reorder-pdf-pages",
|
||||
"toolSlug": "reorder-pdf",
|
||||
"category": "PDF",
|
||||
"focusKeyword": { "en": "reorder pdf pages", "ar": "إعادة ترتيب صفحات PDF" },
|
||||
"supportingKeywords": {
|
||||
"en": ["rearrange pdf pages", "organize pdf pages", "sort pages in pdf"],
|
||||
"ar": ["إعادة ترتيب صفحات pdf", "تنظيم صفحات pdf", "تبديل صفحات pdf"]
|
||||
},
|
||||
"benefit": {
|
||||
"en": "Fix page order in PDFs before sharing, printing, or merging with other files.",
|
||||
"ar": "أصلح ترتيب الصفحات في ملفات PDF قبل المشاركة أو الطباعة أو الدمج مع ملفات أخرى."
|
||||
},
|
||||
"useCase": {
|
||||
"en": "Useful for reports, scanned batches, contracts, and course packs.",
|
||||
"ar": "مفيد للتقارير والدفعات الممسوحة ضوئياً والعقود وحزم الدروس."
|
||||
},
|
||||
"relatedCollectionSlugs": ["best-pdf-tools", "free-pdf-tools-online"]
|
||||
},
|
||||
{
|
||||
"slug": "rotate-pdf-pages",
|
||||
"toolSlug": "rotate-pdf",
|
||||
"category": "PDF",
|
||||
"focusKeyword": { "en": "rotate pdf pages", "ar": "تدوير صفحات PDF" },
|
||||
"supportingKeywords": {
|
||||
"en": ["rotate pdf online", "fix pdf orientation", "turn pdf pages"],
|
||||
"ar": ["تدوير pdf", "تصحيح اتجاه pdf", "إدارة صفحات pdf"]
|
||||
},
|
||||
"benefit": {
|
||||
"en": "Correct sideways or upside-down PDF pages so they read properly on screen and on paper.",
|
||||
"ar": "صحّح صفحات PDF المائلة أو المقلوبة حتى تُقرأ بشكل صحيح على الشاشة وعلى الورق."
|
||||
},
|
||||
"useCase": {
|
||||
"en": "Common for scans, phone-captured documents, and mixed page sets.",
|
||||
"ar": "شائع للملفات الممسوحة ضوئياً والمستندات الملتقطة بالجوال ومجموعات الصفحات المختلطة."
|
||||
},
|
||||
"relatedCollectionSlugs": ["best-pdf-tools", "scanned-document-tools"]
|
||||
},
|
||||
{
|
||||
"slug": "add-page-numbers-to-pdf",
|
||||
"toolSlug": "page-numbers",
|
||||
"category": "PDF",
|
||||
"focusKeyword": { "en": "add page numbers to pdf", "ar": "إضافة أرقام الصفحات إلى PDF" },
|
||||
"supportingKeywords": {
|
||||
"en": ["pdf page numbering", "number pdf pages", "insert page numbers pdf"],
|
||||
"ar": ["إضافة أرقام للصفحات في pdf", "ترقيم صفحات pdf", "أرقام صفحات pdf"]
|
||||
},
|
||||
"benefit": {
|
||||
"en": "Add consistent numbering to PDFs so longer documents are easier to reference and review.",
|
||||
"ar": "أضف ترقيمًا ثابتًا إلى ملفات PDF حتى يسهل الرجوع إلى المستندات الطويلة ومراجعتها."
|
||||
},
|
||||
"useCase": {
|
||||
"en": "Useful for legal files, manuals, reports, and printed course packs.",
|
||||
"ar": "مفيد للملفات القانونية والأدلة والتقارير وحزم الدراسة المطبوعة."
|
||||
},
|
||||
"relatedCollectionSlugs": ["best-pdf-tools", "office-to-pdf-tools"]
|
||||
},
|
||||
{
|
||||
"slug": "protect-pdf-with-password",
|
||||
"toolSlug": "protect-pdf",
|
||||
"category": "PDF",
|
||||
"focusKeyword": { "en": "protect pdf with password", "ar": "حماية PDF بكلمة مرور" },
|
||||
"supportingKeywords": {
|
||||
"en": ["password protect pdf", "secure pdf online", "encrypt pdf file"],
|
||||
"ar": ["حماية pdf بكلمة مرور", "تأمين ملف pdf", "تشفير pdf"]
|
||||
},
|
||||
"benefit": {
|
||||
"en": "Restrict access to PDFs before sending them outside your team or organization.",
|
||||
"ar": "قيّد الوصول إلى ملفات PDF قبل إرسالها خارج فريقك أو مؤسستك."
|
||||
},
|
||||
"useCase": {
|
||||
"en": "Useful for HR, finance, legal, and sensitive client documents.",
|
||||
"ar": "مفيد لوثائق الموارد البشرية والمالية والقانونية ووثائق العملاء الحساسة."
|
||||
},
|
||||
"relatedCollectionSlugs": ["secure-pdf-tools", "best-pdf-tools"]
|
||||
},
|
||||
{
|
||||
"slug": "unlock-pdf-online",
|
||||
"toolSlug": "unlock-pdf",
|
||||
"category": "PDF",
|
||||
"focusKeyword": { "en": "unlock pdf online", "ar": "فتح قفل PDF أونلاين" },
|
||||
"supportingKeywords": {
|
||||
"en": ["unlock protected pdf", "remove password from pdf", "decrypt pdf online"],
|
||||
"ar": ["فتح قفل pdf أونلاين", "إزالة كلمة المرور من pdf", "فك حماية pdf"]
|
||||
},
|
||||
"benefit": {
|
||||
"en": "Open up protected PDFs that you are authorized to use so the next editing or sharing step is easier.",
|
||||
"ar": "افتح ملفات PDF المحمية التي لديك تصريح باستخدامها حتى تصبح الخطوة التالية من التعديل أو المشاركة أسهل."
|
||||
},
|
||||
"useCase": {
|
||||
"en": "Helpful before merging, printing, annotating, or converting files.",
|
||||
"ar": "مفيد قبل الدمج أو الطباعة أو التعليق أو تحويل الملفات."
|
||||
},
|
||||
"relatedCollectionSlugs": ["secure-pdf-tools", "free-pdf-tools-online"]
|
||||
},
|
||||
{
|
||||
"slug": "watermark-pdf-online",
|
||||
"toolSlug": "watermark-pdf",
|
||||
"category": "PDF",
|
||||
"focusKeyword": { "en": "watermark pdf online", "ar": "وضع علامة مائية على PDF أونلاين" },
|
||||
"supportingKeywords": {
|
||||
"en": ["add watermark to pdf", "pdf watermark online", "brand pdf document"],
|
||||
"ar": ["إضافة علامة مائية إلى pdf", "علامة مائية pdf", "وضع شعار على pdf"]
|
||||
},
|
||||
"benefit": {
|
||||
"en": "Add a visible ownership layer to PDFs before sharing drafts, proofs, or client-facing documents.",
|
||||
"ar": "أضف طبقة ملكية واضحة إلى ملفات PDF قبل مشاركة المسودات أو الإثباتات أو مستندات العملاء."
|
||||
},
|
||||
"useCase": {
|
||||
"en": "Useful for draft reviews, branded exports, and controlled circulation.",
|
||||
"ar": "مفيد لمراجعة المسودات والتصدير الممهور بالعلامة التجارية والتوزيع المحدود."
|
||||
},
|
||||
"relatedCollectionSlugs": ["secure-pdf-tools", "best-pdf-tools"]
|
||||
},
|
||||
{
|
||||
"slug": "remove-watermark-from-pdf",
|
||||
"toolSlug": "remove-watermark-pdf",
|
||||
"category": "PDF",
|
||||
"focusKeyword": { "en": "remove watermark from pdf", "ar": "إزالة العلامة المائية من PDF" },
|
||||
"supportingKeywords": {
|
||||
"en": ["delete pdf watermark", "clean pdf watermark", "remove text watermark pdf"],
|
||||
"ar": ["إزالة العلامة المائية من pdf", "حذف العلامة المائية pdf", "تنظيف pdf من العلامة المائية"]
|
||||
},
|
||||
"benefit": {
|
||||
"en": "Clean up PDFs by removing unwanted watermark text when you are working with authorized source files.",
|
||||
"ar": "نظّف ملفات PDF بإزالة نص العلامة المائية غير المرغوب عندما تعمل على ملفات مصدر مصرح بها."
|
||||
},
|
||||
"useCase": {
|
||||
"en": "Useful for final copies, internal working versions, and cleaned archives.",
|
||||
"ar": "مفيد للنسخ النهائية ونسخ العمل الداخلية والأرشيفات النظيفة."
|
||||
},
|
||||
"relatedCollectionSlugs": ["secure-pdf-tools", "free-pdf-tools-online"]
|
||||
},
|
||||
{
|
||||
"slug": "edit-pdf-online-free",
|
||||
"toolSlug": "pdf-editor",
|
||||
"category": "PDF",
|
||||
"focusKeyword": { "en": "edit pdf online free", "ar": "تعديل PDF أونلاين مجاناً" },
|
||||
"supportingKeywords": {
|
||||
"en": ["free pdf editor online", "annotate pdf", "modify pdf online"],
|
||||
"ar": ["تعديل pdf مجاناً", "محرر pdf أونلاين", "تعديل ملف pdf"]
|
||||
},
|
||||
"benefit": {
|
||||
"en": "Make quick PDF edits and annotations in the browser without switching to heavier desktop software.",
|
||||
"ar": "أجرِ تعديلات سريعة وتعليقات على PDF داخل المتصفح بدون الانتقال إلى برامج سطح مكتب أثقل."
|
||||
},
|
||||
"useCase": {
|
||||
"en": "Useful for notes, approvals, markup, and light document cleanup.",
|
||||
"ar": "مفيد للملاحظات والموافقات ووضع العلامات وتنظيف المستندات بشكل خفيف."
|
||||
},
|
||||
"relatedCollectionSlugs": ["free-pdf-tools-online", "best-pdf-tools"]
|
||||
},
|
||||
{
|
||||
"slug": "pdf-to-excel-online",
|
||||
"toolSlug": "pdf-to-excel",
|
||||
"category": "Convert",
|
||||
"focusKeyword": { "en": "pdf to excel online", "ar": "تحويل PDF إلى Excel أونلاين" },
|
||||
"supportingKeywords": {
|
||||
"en": ["convert pdf to xlsx", "pdf table to excel", "pdf spreadsheet converter"],
|
||||
"ar": ["تحويل pdf إلى excel", "pdf إلى xlsx", "جدول pdf إلى excel"]
|
||||
},
|
||||
"benefit": {
|
||||
"en": "Move tabular data out of PDF and into Excel so teams can filter, calculate, and reuse it.",
|
||||
"ar": "انقل البيانات الجدولية من PDF إلى Excel حتى تتمكن الفرق من التصفية والحساب وإعادة الاستخدام."
|
||||
},
|
||||
"useCase": {
|
||||
"en": "Helpful for invoices, statements, reports, and operations data.",
|
||||
"ar": "مفيد للفواتير والكشوفات والتقارير وبيانات العمليات."
|
||||
},
|
||||
"relatedCollectionSlugs": ["pdf-converter-tools", "office-to-pdf-tools"]
|
||||
},
|
||||
{
|
||||
"slug": "extract-tables-from-pdf",
|
||||
"toolSlug": "extract-tables",
|
||||
"category": "AI",
|
||||
"focusKeyword": { "en": "extract tables from pdf", "ar": "استخراج الجداول من PDF" },
|
||||
"supportingKeywords": {
|
||||
"en": ["pdf table extractor", "capture tables from pdf", "pdf table to spreadsheet"],
|
||||
"ar": ["استخراج الجداول من pdf", "أداة جداول pdf", "تحويل جدول pdf"]
|
||||
},
|
||||
"benefit": {
|
||||
"en": "Pull structured tables from PDF pages when data needs to move into spreadsheets or analysis tools.",
|
||||
"ar": "استخرج الجداول المنظمة من صفحات PDF عندما تحتاج البيانات إلى الانتقال إلى جداول البيانات أو أدوات التحليل."
|
||||
},
|
||||
"useCase": {
|
||||
"en": "Useful for finance data, procurement sheets, and operational reporting.",
|
||||
"ar": "مفيد للبيانات المالية وجداول المشتريات وتقارير العمليات."
|
||||
},
|
||||
"relatedCollectionSlugs": ["ai-document-tools", "pdf-converter-tools"]
|
||||
},
|
||||
{
|
||||
"slug": "html-to-pdf-online",
|
||||
"toolSlug": "html-to-pdf",
|
||||
"category": "Convert",
|
||||
"focusKeyword": { "en": "html to pdf online", "ar": "تحويل HTML إلى PDF أونلاين" },
|
||||
"supportingKeywords": {
|
||||
"en": ["convert html to pdf", "webpage to pdf", "html file to pdf"],
|
||||
"ar": ["تحويل html إلى pdf", "صفحة ويب إلى pdf", "ملف html إلى pdf"]
|
||||
},
|
||||
"benefit": {
|
||||
"en": "Capture web layouts as PDFs for sharing, approval, printing, or archiving.",
|
||||
"ar": "التقط تنسيقات الويب كملفات PDF للمشاركة أو الاعتماد أو الطباعة أو الأرشفة."
|
||||
},
|
||||
"useCase": {
|
||||
"en": "Helpful for invoices, landing page proofs, templates, and documentation exports.",
|
||||
"ar": "مفيد للفواتير وإثباتات صفحات الهبوط والقوالب وتصدير الوثائق."
|
||||
},
|
||||
"relatedCollectionSlugs": ["convert-files-online", "office-to-pdf-tools"]
|
||||
},
|
||||
{
|
||||
"slug": "scan-pdf-to-text",
|
||||
"toolSlug": "ocr",
|
||||
"category": "AI",
|
||||
"focusKeyword": { "en": "scan pdf to text", "ar": "تحويل PDF الممسوح إلى نص" },
|
||||
"supportingKeywords": {
|
||||
"en": ["ocr scanned pdf", "scanned pdf text extraction", "scan to editable text"],
|
||||
"ar": ["تحويل pdf الممسوح إلى نص", "ocr pdf ممسوح", "استخراج النص من pdf ممسوح"]
|
||||
},
|
||||
"benefit": {
|
||||
"en": "Use OCR to recover editable text from scanned PDFs that would otherwise stay image-based.",
|
||||
"ar": "استخدم OCR لاستعادة نص قابل للتحرير من ملفات PDF الممسوحة ضوئياً والتي كانت ستبقى معتمدة على الصور."
|
||||
},
|
||||
"useCase": {
|
||||
"en": "Best for archive scans, old records, paperwork, and compliance files.",
|
||||
"ar": "مناسب للأرشيفات الممسوحة والملفات القديمة والأوراق الإدارية وملفات الامتثال."
|
||||
},
|
||||
"relatedCollectionSlugs": ["scanned-document-tools", "ai-document-tools"]
|
||||
},
|
||||
{
|
||||
"slug": "chat-with-pdf",
|
||||
"toolSlug": "chat-pdf",
|
||||
"category": "AI",
|
||||
"focusKeyword": { "en": "chat with pdf", "ar": "الدردشة مع PDF" },
|
||||
"supportingKeywords": {
|
||||
"en": ["ask pdf questions", "ai pdf chat", "chat pdf online"],
|
||||
"ar": ["الدردشة مع pdf", "سؤال pdf بالذكاء الاصطناعي", "chat pdf"]
|
||||
},
|
||||
"benefit": {
|
||||
"en": "Ask direct questions about long PDF documents instead of manually searching page by page.",
|
||||
"ar": "اسأل أسئلة مباشرة عن ملفات PDF الطويلة بدلاً من البحث اليدوي صفحةً صفحة."
|
||||
},
|
||||
"useCase": {
|
||||
"en": "Useful for contracts, manuals, research papers, and policy reviews.",
|
||||
"ar": "مفيد للعقود والأدلة وأوراق البحث ومراجعة السياسات."
|
||||
},
|
||||
"relatedCollectionSlugs": ["ai-document-tools", "scanned-document-tools"]
|
||||
},
|
||||
{
|
||||
"slug": "summarize-pdf-online",
|
||||
"toolSlug": "summarize-pdf",
|
||||
"category": "AI",
|
||||
"focusKeyword": { "en": "summarize pdf online", "ar": "تلخيص PDF أونلاين" },
|
||||
"supportingKeywords": {
|
||||
"en": ["pdf summary tool", "summarize document pdf", "ai pdf summary"],
|
||||
"ar": ["تلخيص pdf أونلاين", "ملخص pdf", "تلخيص مستند pdf"]
|
||||
},
|
||||
"benefit": {
|
||||
"en": "Extract the core points from long PDF files faster so review cycles and decision-making move sooner.",
|
||||
"ar": "استخرج النقاط الأساسية من ملفات PDF الطويلة بسرعة أكبر حتى تتحرك دورات المراجعة واتخاذ القرار أسرع."
|
||||
},
|
||||
"useCase": {
|
||||
"en": "Great for research, internal memos, reports, and customer documents.",
|
||||
"ar": "ممتاز للبحث والمذكرات الداخلية والتقارير ووثائق العملاء."
|
||||
},
|
||||
"relatedCollectionSlugs": ["ai-document-tools", "best-pdf-tools"]
|
||||
},
|
||||
{
|
||||
"slug": "translate-pdf-online",
|
||||
"toolSlug": "translate-pdf",
|
||||
"category": "AI",
|
||||
"focusKeyword": { "en": "translate pdf online", "ar": "ترجمة PDF أونلاين" },
|
||||
"supportingKeywords": {
|
||||
"en": ["pdf translator online", "translate document pdf", "multilingual pdf translation"],
|
||||
"ar": ["ترجمة pdf أونلاين", "مترجم pdf", "ترجمة مستند pdf"]
|
||||
},
|
||||
"benefit": {
|
||||
"en": "Translate PDF content so multilingual teams can understand and share documents faster.",
|
||||
"ar": "ترجم محتوى PDF حتى تتمكن الفرق متعددة اللغات من فهم المستندات ومشاركتها بسرعة أكبر."
|
||||
},
|
||||
"useCase": {
|
||||
"en": "Useful for cross-border teams, customer support, procurement, and research.",
|
||||
"ar": "مفيد للفرق العابرة للحدود ودعم العملاء والمشتريات والبحث."
|
||||
},
|
||||
"relatedCollectionSlugs": ["ai-document-tools", "arabic-pdf-tools"]
|
||||
},
|
||||
{
|
||||
"slug": "convert-image-to-pdf",
|
||||
"toolSlug": "images-to-pdf",
|
||||
"category": "PDF",
|
||||
"focusKeyword": { "en": "convert image to pdf", "ar": "تحويل الصورة إلى PDF" },
|
||||
"supportingKeywords": {
|
||||
"en": ["image to pdf converter", "photo to pdf online", "turn image into pdf"],
|
||||
"ar": ["تحويل الصورة إلى pdf", "صورة إلى pdf", "تحويل الصور الى pdf"]
|
||||
},
|
||||
"benefit": {
|
||||
"en": "Wrap image files in PDF format when the receiving system expects documents rather than photos.",
|
||||
"ar": "حوّل ملفات الصور إلى صيغة PDF عندما يتوقع النظام المستقبل مستندات بدلاً من صور."
|
||||
},
|
||||
"useCase": {
|
||||
"en": "Common for applications, government forms, receipts, and proof uploads.",
|
||||
"ar": "شائع لطلبات التقديم والنماذج الحكومية والإيصالات ورفع ملفات الإثبات."
|
||||
},
|
||||
"relatedCollectionSlugs": ["image-to-pdf-tools", "convert-files-online"]
|
||||
},
|
||||
{
|
||||
"slug": "convert-webp-to-jpg",
|
||||
"toolSlug": "image-converter",
|
||||
"category": "Image",
|
||||
"focusKeyword": { "en": "convert webp to jpg", "ar": "تحويل WebP إلى JPG" },
|
||||
"supportingKeywords": {
|
||||
"en": ["webp to jpg online", "change webp to jpeg", "image format converter"],
|
||||
"ar": ["تحويل webp إلى jpg", "webp إلى jpeg", "محول صيغ الصور"]
|
||||
},
|
||||
"benefit": {
|
||||
"en": "Make WebP images compatible with apps, clients, and workflows that still expect JPG files.",
|
||||
"ar": "اجعل صور WebP متوافقة مع التطبيقات والعملاء ومسارات العمل التي لا تزال تتوقع ملفات JPG."
|
||||
},
|
||||
"useCase": {
|
||||
"en": "Useful for uploads, ecommerce operations, publishing, and legacy systems.",
|
||||
"ar": "مفيد للرفع وعمليات التجارة الإلكترونية والنشر والأنظمة القديمة."
|
||||
},
|
||||
"relatedCollectionSlugs": ["online-image-tools", "convert-files-online"]
|
||||
},
|
||||
{
|
||||
"slug": "resize-image-online",
|
||||
"toolSlug": "image-resize",
|
||||
"category": "Image",
|
||||
"focusKeyword": { "en": "resize image online", "ar": "تغيير حجم الصورة أونلاين" },
|
||||
"supportingKeywords": {
|
||||
"en": ["image resizer online", "change image dimensions", "resize photo"],
|
||||
"ar": ["تغيير حجم الصورة أونلاين", "مغير حجم الصورة", "تعديل أبعاد الصورة"]
|
||||
},
|
||||
"benefit": {
|
||||
"en": "Adjust image dimensions quickly for upload requirements, web layouts, or marketplace listings.",
|
||||
"ar": "عدّل أبعاد الصور بسرعة لمتطلبات الرفع أو تنسيقات الويب أو قوائم المتاجر."
|
||||
},
|
||||
"useCase": {
|
||||
"en": "Useful for avatars, banners, product listings, and CMS uploads.",
|
||||
"ar": "مفيد للصور الشخصية والبنرات وقوائم المنتجات ورفع ملفات أنظمة إدارة المحتوى."
|
||||
},
|
||||
"relatedCollectionSlugs": ["online-image-tools", "convert-files-online"]
|
||||
},
|
||||
{
|
||||
"slug": "compress-image-online",
|
||||
"toolSlug": "compress-image",
|
||||
"category": "Image",
|
||||
"focusKeyword": { "en": "compress image online", "ar": "ضغط الصورة أونلاين" },
|
||||
"supportingKeywords": {
|
||||
"en": ["reduce image size", "image compressor online", "shrink photo file"],
|
||||
"ar": ["ضغط الصورة أونلاين", "تقليل حجم الصورة", "ضغط ملف الصورة"]
|
||||
},
|
||||
"benefit": {
|
||||
"en": "Lower image file sizes for faster pages, smaller uploads, and easier sharing.",
|
||||
"ar": "خفّض أحجام ملفات الصور لصفحات أسرع وملفات رفع أصغر ومشاركة أسهل."
|
||||
},
|
||||
"useCase": {
|
||||
"en": "Useful for web publishing, product catalogs, forms, and mobile transfers.",
|
||||
"ar": "مفيد للنشر على الويب وكتالوجات المنتجات والنماذج والنقل عبر الجوال."
|
||||
},
|
||||
"relatedCollectionSlugs": ["online-image-tools", "free-pdf-tools-online"]
|
||||
},
|
||||
{
|
||||
"slug": "remove-image-background",
|
||||
"toolSlug": "remove-background",
|
||||
"category": "Image",
|
||||
"focusKeyword": { "en": "remove image background", "ar": "إزالة خلفية الصورة" },
|
||||
"supportingKeywords": {
|
||||
"en": ["background remover online", "transparent background tool", "remove photo background"],
|
||||
"ar": ["إزالة خلفية الصورة", "حذف خلفية الصورة", "أداة إزالة الخلفية"]
|
||||
},
|
||||
"benefit": {
|
||||
"en": "Create transparent-background images quickly for storefronts, ads, and branded assets.",
|
||||
"ar": "أنشئ صوراً بخلفية شفافة بسرعة للمتاجر والإعلانات والأصول ذات العلامة التجارية."
|
||||
},
|
||||
"useCase": {
|
||||
"en": "Useful for ecommerce, presentations, catalog design, and social content.",
|
||||
"ar": "مفيد للتجارة الإلكترونية والعروض وتصميم الكتالوجات والمحتوى الاجتماعي."
|
||||
},
|
||||
"relatedCollectionSlugs": ["online-image-tools", "convert-files-online"]
|
||||
}
|
||||
],
|
||||
"collectionPageSeeds": [
|
||||
{
|
||||
"slug": "best-pdf-tools",
|
||||
"focusKeyword": { "en": "best pdf tools", "ar": "أفضل أدوات PDF" },
|
||||
"supportingKeywords": {
|
||||
"en": ["online pdf toolkit", "top pdf tools", "document workflows"],
|
||||
"ar": ["أفضل أدوات pdf", "مجموعة أدوات pdf", "أدوات المستندات"]
|
||||
},
|
||||
"introAngle": {
|
||||
"en": "Group the highest-utility PDF workflows in one place so users can move from search intent to the right tool quickly.",
|
||||
"ar": "اجمع أكثر مسارات PDF فائدة في مكان واحد حتى ينتقل المستخدم من نية البحث إلى الأداة المناسبة بسرعة."
|
||||
},
|
||||
"targetToolSlugs": ["pdf-to-word", "word-to-pdf", "compress-pdf", "merge-pdf", "split-pdf", "unlock-pdf"],
|
||||
"relatedCollectionSlugs": ["free-pdf-tools-online", "pdf-converter-tools"]
|
||||
},
|
||||
{
|
||||
"slug": "free-pdf-tools-online",
|
||||
"focusKeyword": { "en": "free pdf tools online", "ar": "أدوات PDF مجانية أونلاين" },
|
||||
"supportingKeywords": {
|
||||
"en": ["free online pdf tools", "browser pdf utilities", "pdf tools without signup"],
|
||||
"ar": ["أدوات pdf مجانية أونلاين", "أدوات pdf بدون تسجيل", "أدوات pdf من المتصفح"]
|
||||
},
|
||||
"introAngle": {
|
||||
"en": "Capture users who want practical browser-based PDF work without downloads, subscriptions, or account setup.",
|
||||
"ar": "استهدف المستخدمين الذين يريدون إنجاز أعمال PDF من المتصفح بدون تنزيلات أو اشتراكات أو إعداد حساب."
|
||||
},
|
||||
"targetToolSlugs": ["compress-pdf", "merge-pdf", "split-pdf", "unlock-pdf", "protect-pdf", "pdf-editor"],
|
||||
"relatedCollectionSlugs": ["best-pdf-tools", "secure-pdf-tools"]
|
||||
},
|
||||
{
|
||||
"slug": "convert-files-online",
|
||||
"focusKeyword": { "en": "convert files online", "ar": "تحويل الملفات أونلاين" },
|
||||
"supportingKeywords": {
|
||||
"en": ["online file converter", "document conversion tools", "format converter online"],
|
||||
"ar": ["تحويل الملفات أونلاين", "محول ملفات أونلاين", "أدوات تحويل الصيغ"]
|
||||
},
|
||||
"introAngle": {
|
||||
"en": "Bring together the most common format changes across PDF, Office, images, and HTML in one discoverable page.",
|
||||
"ar": "اجمع أكثر عمليات تغيير الصيغ شيوعاً عبر PDF وأوفيس والصور وHTML في صفحة واحدة قابلة للاكتشاف."
|
||||
},
|
||||
"targetToolSlugs": ["pdf-to-word", "word-to-pdf", "images-to-pdf", "image-converter", "html-to-pdf", "pdf-to-excel"],
|
||||
"relatedCollectionSlugs": ["pdf-converter-tools", "online-image-tools"]
|
||||
},
|
||||
{
|
||||
"slug": "pdf-converter-tools",
|
||||
"focusKeyword": { "en": "pdf converter tools", "ar": "أدوات تحويل PDF" },
|
||||
"supportingKeywords": {
|
||||
"en": ["pdf conversion tools", "convert from pdf", "convert to pdf workflows"],
|
||||
"ar": ["أدوات تحويل pdf", "تحويل من pdf", "التحويل إلى pdf"]
|
||||
},
|
||||
"introAngle": {
|
||||
"en": "Capture conversion-intent traffic around moving content between PDF and editable, shareable, or image-based formats.",
|
||||
"ar": "استهدف ترافيك نية التحويل حول نقل المحتوى بين PDF والصيغ القابلة للتحرير أو المشاركة أو المعتمدة على الصور."
|
||||
},
|
||||
"targetToolSlugs": ["pdf-to-word", "word-to-pdf", "pdf-to-excel", "pdf-to-images", "images-to-pdf", "html-to-pdf"],
|
||||
"relatedCollectionSlugs": ["convert-files-online", "office-to-pdf-tools"]
|
||||
},
|
||||
{
|
||||
"slug": "secure-pdf-tools",
|
||||
"focusKeyword": { "en": "secure pdf tools", "ar": "أدوات تأمين PDF" },
|
||||
"supportingKeywords": {
|
||||
"en": ["pdf security tools", "protect and unlock pdf", "pdf permission workflows"],
|
||||
"ar": ["أدوات تأمين pdf", "حماية وفتح pdf", "صلاحيات pdf"]
|
||||
},
|
||||
"introAngle": {
|
||||
"en": "Cover the workflows people search when documents need access control, branding, or safer circulation.",
|
||||
"ar": "غطِ مسارات العمل التي يبحث عنها المستخدمون عندما تحتاج المستندات إلى التحكم في الوصول أو العلامة التجارية أو التوزيع الآمن."
|
||||
},
|
||||
"targetToolSlugs": ["protect-pdf", "unlock-pdf", "watermark-pdf", "remove-watermark-pdf", "compress-pdf", "merge-pdf"],
|
||||
"relatedCollectionSlugs": ["best-pdf-tools", "free-pdf-tools-online"]
|
||||
},
|
||||
{
|
||||
"slug": "ai-document-tools",
|
||||
"focusKeyword": { "en": "ai document tools", "ar": "أدوات المستندات بالذكاء الاصطناعي" },
|
||||
"supportingKeywords": {
|
||||
"en": ["ai pdf tools", "smart document workflows", "document ai online"],
|
||||
"ar": ["أدوات pdf بالذكاء الاصطناعي", "أدوات مستندات ذكية", "ذكاء اصطناعي للمستندات"]
|
||||
},
|
||||
"introAngle": {
|
||||
"en": "Group AI-assisted document workflows for question answering, OCR, translation, table extraction, and summarization.",
|
||||
"ar": "اجمع مسارات المستندات المدعومة بالذكاء الاصطناعي للأسئلة وOCR والترجمة واستخراج الجداول والتلخيص."
|
||||
},
|
||||
"targetToolSlugs": ["chat-pdf", "summarize-pdf", "translate-pdf", "ocr", "extract-tables", "pdf-flowchart"],
|
||||
"relatedCollectionSlugs": ["scanned-document-tools", "arabic-pdf-tools"]
|
||||
},
|
||||
{
|
||||
"slug": "image-to-pdf-tools",
|
||||
"focusKeyword": { "en": "image to pdf tools", "ar": "أدوات تحويل الصور إلى PDF" },
|
||||
"supportingKeywords": {
|
||||
"en": ["images into pdf", "photo to pdf workflows", "scan images to pdf"],
|
||||
"ar": ["تحويل الصور إلى pdf", "صورة إلى pdf", "أدوات صور إلى pdf"]
|
||||
},
|
||||
"introAngle": {
|
||||
"en": "Target users who start with image files but need a document-friendly PDF result for submission or storage.",
|
||||
"ar": "استهدف المستخدمين الذين يبدأون بملفات صور لكنهم يحتاجون نتيجة PDF مناسبة للتقديم أو التخزين."
|
||||
},
|
||||
"targetToolSlugs": ["images-to-pdf", "pdf-to-images", "image-resize", "compress-image", "remove-background", "image-converter"],
|
||||
"relatedCollectionSlugs": ["online-image-tools", "convert-files-online"]
|
||||
},
|
||||
{
|
||||
"slug": "online-image-tools",
|
||||
"focusKeyword": { "en": "online image tools", "ar": "أدوات الصور أونلاين" },
|
||||
"supportingKeywords": {
|
||||
"en": ["browser image tools", "image editing tools online", "online photo utilities"],
|
||||
"ar": ["أدوات الصور أونلاين", "أدوات تعديل الصور", "أدوات الصور من المتصفح"]
|
||||
},
|
||||
"introAngle": {
|
||||
"en": "Group lightweight image workflows for format changes, compression, resizing, cleanup, and PDF handoff.",
|
||||
"ar": "اجمع مسارات الصور الخفيفة لتغيير الصيغ والضغط وتغيير الحجم والتنظيف والتمرير إلى PDF."
|
||||
},
|
||||
"targetToolSlugs": ["image-converter", "image-resize", "compress-image", "remove-background", "images-to-pdf", "image-crop"],
|
||||
"relatedCollectionSlugs": ["image-to-pdf-tools", "convert-files-online"]
|
||||
},
|
||||
{
|
||||
"slug": "office-to-pdf-tools",
|
||||
"focusKeyword": { "en": "office to pdf tools", "ar": "أدوات تحويل ملفات أوفيس إلى PDF" },
|
||||
"supportingKeywords": {
|
||||
"en": ["word excel powerpoint to pdf", "office document pdf conversion", "export office files to pdf"],
|
||||
"ar": ["تحويل ملفات أوفيس إلى pdf", "word excel powerpoint إلى pdf", "تصدير ملفات أوفيس إلى pdf"]
|
||||
},
|
||||
"introAngle": {
|
||||
"en": "Focus on workflows where teams convert Office documents into portable PDF files for sharing or approval.",
|
||||
"ar": "ركّز على المسارات التي تحول فيها الفرق ملفات أوفيس إلى PDF قابل للنقل للمشاركة أو الاعتماد."
|
||||
},
|
||||
"targetToolSlugs": ["word-to-pdf", "excel-to-pdf", "pptx-to-pdf", "html-to-pdf", "sign-pdf", "pdf-editor"],
|
||||
"relatedCollectionSlugs": ["convert-files-online", "pdf-converter-tools"]
|
||||
},
|
||||
{
|
||||
"slug": "scanned-document-tools",
|
||||
"focusKeyword": { "en": "scanned document tools", "ar": "أدوات المستندات الممسوحة ضوئياً" },
|
||||
"supportingKeywords": {
|
||||
"en": ["scan to text tools", "ocr pdf tools", "scan document workflows"],
|
||||
"ar": ["أدوات المستندات الممسوحة", "ocr للمستندات", "مسارات المستندات الممسوحة"]
|
||||
},
|
||||
"introAngle": {
|
||||
"en": "Capture users who need OCR, cleanup, compression, and reuse workflows for image-heavy or scanned files.",
|
||||
"ar": "استهدف المستخدمين الذين يحتاجون إلى OCR والتنظيف والضغط وإعادة الاستخدام للملفات الممسوحة أو المعتمدة على الصور."
|
||||
},
|
||||
"targetToolSlugs": ["ocr", "compress-pdf", "pdf-to-word", "extract-tables", "rotate-pdf", "pdf-to-images"],
|
||||
"relatedCollectionSlugs": ["ai-document-tools", "arabic-pdf-tools"]
|
||||
},
|
||||
{
|
||||
"slug": "arabic-pdf-tools",
|
||||
"focusKeyword": { "en": "arabic pdf tools", "ar": "أدوات PDF العربية" },
|
||||
"supportingKeywords": {
|
||||
"en": ["pdf tools for arabic documents", "arabic document workflows", "rtl pdf tools"],
|
||||
"ar": ["أدوات pdf العربية", "أدوات للمستندات العربية", "pdf للغة العربية"]
|
||||
},
|
||||
"introAngle": {
|
||||
"en": "Position Dociva for Arabic-language document workflows where RTL support and bilingual search intent matter.",
|
||||
"ar": "ضع Dociva في موقع قوي لمسارات المستندات العربية حيث يكون دعم RTL ونية البحث ثنائية اللغة مهمين."
|
||||
},
|
||||
"targetToolSlugs": ["pdf-to-word", "word-to-pdf", "ocr", "translate-pdf", "images-to-pdf", "compress-pdf"],
|
||||
"relatedCollectionSlugs": ["ai-document-tools", "best-pdf-tools"]
|
||||
}
|
||||
]
|
||||
}
|
||||
30
frontend/src/seo/seoData.test.ts
Normal file
30
frontend/src/seo/seoData.test.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import {
|
||||
PROGRAMMATIC_TOOL_PAGES,
|
||||
SEO_COLLECTION_PAGES,
|
||||
SEO_TOTAL_PAGE_COUNT,
|
||||
getLocalizedSeoLandingPaths,
|
||||
} from '@/seo/seoData';
|
||||
|
||||
describe('SEO data engine', () => {
|
||||
it('generates at least 50 bilingual SEO pages', () => {
|
||||
expect(SEO_TOTAL_PAGE_COUNT).toBeGreaterThanOrEqual(50);
|
||||
});
|
||||
|
||||
it('has no duplicate english slugs', () => {
|
||||
const englishPaths = getLocalizedSeoLandingPaths('en');
|
||||
expect(new Set(englishPaths).size).toBe(englishPaths.length);
|
||||
});
|
||||
|
||||
it('generates matching arabic localized paths', () => {
|
||||
const englishPaths = getLocalizedSeoLandingPaths('en');
|
||||
const arabicPaths = getLocalizedSeoLandingPaths('ar');
|
||||
expect(arabicPaths.length).toBe(englishPaths.length);
|
||||
expect(arabicPaths.every((path) => path.startsWith('/ar/'))).toBe(true);
|
||||
});
|
||||
|
||||
it('keeps both tool and collection SEO inventories populated', () => {
|
||||
expect(PROGRAMMATIC_TOOL_PAGES.length).toBeGreaterThan(30);
|
||||
expect(SEO_COLLECTION_PAGES.length).toBeGreaterThanOrEqual(10);
|
||||
});
|
||||
});
|
||||
187
frontend/src/seo/seoData.ts
Normal file
187
frontend/src/seo/seoData.ts
Normal file
@@ -0,0 +1,187 @@
|
||||
import seoSeedConfig from '@/seo/seoData.json';
|
||||
import type {
|
||||
LocalizedText,
|
||||
LocalizedTextList,
|
||||
ProgrammaticToolPage,
|
||||
SeoCollectionPage,
|
||||
SeoFaqTemplate,
|
||||
SeoLocale,
|
||||
} from '@/config/seoPages';
|
||||
|
||||
interface ToolPageSeed {
|
||||
slug: string;
|
||||
toolSlug: string;
|
||||
category: 'PDF' | 'Image' | 'AI' | 'Convert' | 'Utility';
|
||||
focusKeyword: LocalizedText;
|
||||
supportingKeywords: LocalizedTextList;
|
||||
benefit: LocalizedText;
|
||||
useCase: LocalizedText;
|
||||
relatedCollectionSlugs: string[];
|
||||
}
|
||||
|
||||
interface CollectionPageSeed {
|
||||
slug: string;
|
||||
focusKeyword: LocalizedText;
|
||||
supportingKeywords: LocalizedTextList;
|
||||
introAngle: LocalizedText;
|
||||
targetToolSlugs: string[];
|
||||
relatedCollectionSlugs: string[];
|
||||
}
|
||||
|
||||
interface SeoSeedConfig {
|
||||
toolPageSeeds: ToolPageSeed[];
|
||||
collectionPageSeeds: CollectionPageSeed[];
|
||||
}
|
||||
|
||||
const seedConfig = seoSeedConfig as SeoSeedConfig;
|
||||
|
||||
function buildToolFaqs(seed: ToolPageSeed): SeoFaqTemplate[] {
|
||||
return [
|
||||
{
|
||||
question: {
|
||||
en: `When should I use ${seed.focusKeyword.en}?`,
|
||||
ar: `متى أستخدم ${seed.focusKeyword.ar}؟`,
|
||||
},
|
||||
answer: {
|
||||
en: `${seed.useCase.en} ${seed.benefit.en}`,
|
||||
ar: `${seed.useCase.ar} ${seed.benefit.ar}`,
|
||||
},
|
||||
},
|
||||
{
|
||||
question: {
|
||||
en: `What makes ${seed.focusKeyword.en} useful online?`,
|
||||
ar: `ما الذي يجعل ${seed.focusKeyword.ar} مفيداً أونلاين؟`,
|
||||
},
|
||||
answer: {
|
||||
en: `Dociva helps you handle this workflow in the browser with secure processing, fast output, and no installation. ${seed.benefit.en}`,
|
||||
ar: `يساعدك Dociva على تنفيذ هذا المسار من المتصفح مع معالجة آمنة ونتيجة سريعة وبدون تثبيت. ${seed.benefit.ar}`,
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
function buildCollectionFaqs(seed: CollectionPageSeed): SeoFaqTemplate[] {
|
||||
return [
|
||||
{
|
||||
question: {
|
||||
en: `What is included in ${seed.focusKeyword.en}?`,
|
||||
ar: `ماذا تتضمن ${seed.focusKeyword.ar}؟`,
|
||||
},
|
||||
answer: {
|
||||
en: `${seed.introAngle.en} This page brings together the main workflows users usually need before downloading, sharing, or archiving files.`,
|
||||
ar: `${seed.introAngle.ar} تجمع هذه الصفحة أهم المسارات التي يحتاجها المستخدمون عادة قبل التنزيل أو المشاركة أو الأرشفة.`,
|
||||
},
|
||||
},
|
||||
{
|
||||
question: {
|
||||
en: `How do I choose the right workflow from ${seed.focusKeyword.en}?`,
|
||||
ar: `كيف أختار المسار المناسب من ${seed.focusKeyword.ar}؟`,
|
||||
},
|
||||
answer: {
|
||||
en: `Start with the outcome you need, then open the matching tool. This collection is designed to reduce guesswork and move directly into execution.`,
|
||||
ar: `ابدأ بالنتيجة التي تحتاجها ثم افتح الأداة المطابقة. صُممت هذه المجموعة لتقليل التخمين والانتقال مباشرة إلى التنفيذ.`,
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
function buildToolSections(seed: ToolPageSeed): Array<{ heading: LocalizedText; body: LocalizedText }> {
|
||||
return [
|
||||
{
|
||||
heading: {
|
||||
en: `Why people search for ${seed.focusKeyword.en}`,
|
||||
ar: `لماذا يبحث المستخدمون عن ${seed.focusKeyword.ar}`,
|
||||
},
|
||||
body: {
|
||||
en: seed.benefit.en,
|
||||
ar: seed.benefit.ar,
|
||||
},
|
||||
},
|
||||
{
|
||||
heading: {
|
||||
en: 'Common use cases',
|
||||
ar: 'حالات الاستخدام الشائعة',
|
||||
},
|
||||
body: {
|
||||
en: seed.useCase.en,
|
||||
ar: seed.useCase.ar,
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
function buildCollectionSections(seed: CollectionPageSeed): Array<{ heading: LocalizedText; body: LocalizedText }> {
|
||||
return [
|
||||
{
|
||||
heading: {
|
||||
en: `What this ${seed.focusKeyword.en} page covers`,
|
||||
ar: `ما الذي تغطيه صفحة ${seed.focusKeyword.ar}`,
|
||||
},
|
||||
body: {
|
||||
en: seed.introAngle.en,
|
||||
ar: seed.introAngle.ar,
|
||||
},
|
||||
},
|
||||
{
|
||||
heading: {
|
||||
en: 'How to use this collection',
|
||||
ar: 'كيفية استخدام هذه المجموعة',
|
||||
},
|
||||
body: {
|
||||
en: 'Choose the workflow that matches the output you need first, then chain cleanup, security, or AI tools only when the file requires them.',
|
||||
ar: 'اختر أولاً مسار العمل الذي يطابق النتيجة التي تحتاجها، ثم أضف أدوات التنظيف أو الأمان أو الذكاء الاصطناعي فقط عندما يتطلب الملف ذلك.',
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
export const PROGRAMMATIC_TOOL_PAGES: ProgrammaticToolPage[] = seedConfig.toolPageSeeds.map((seed) => ({
|
||||
slug: seed.slug,
|
||||
toolSlug: seed.toolSlug,
|
||||
category: seed.category,
|
||||
focusKeyword: seed.focusKeyword,
|
||||
supportingKeywords: seed.supportingKeywords,
|
||||
titleTemplate: {
|
||||
en: `{{focusKeyword}} online | {{brand}}`,
|
||||
ar: `{{focusKeyword}} أونلاين | {{brand}}`,
|
||||
},
|
||||
descriptionTemplate: {
|
||||
en: `${seed.benefit.en} ${seed.useCase.en} Use {{brand}} to complete this workflow online with no signup required.`,
|
||||
ar: `${seed.benefit.ar} ${seed.useCase.ar} استخدم {{brand}} لإتمام هذا المسار أونلاين بدون تسجيل.`,
|
||||
},
|
||||
faqTemplates: buildToolFaqs(seed),
|
||||
relatedCollectionSlugs: seed.relatedCollectionSlugs,
|
||||
contentSections: buildToolSections(seed),
|
||||
}));
|
||||
|
||||
export const SEO_COLLECTION_PAGES: SeoCollectionPage[] = seedConfig.collectionPageSeeds.map((seed) => ({
|
||||
slug: seed.slug,
|
||||
focusKeyword: seed.focusKeyword,
|
||||
supportingKeywords: seed.supportingKeywords,
|
||||
titleTemplate: {
|
||||
en: `{{focusKeyword}} | {{brand}}`,
|
||||
ar: `{{focusKeyword}} | {{brand}}`,
|
||||
},
|
||||
descriptionTemplate: {
|
||||
en: `${seed.introAngle.en} Browse the most relevant workflows in one focused landing page.`,
|
||||
ar: `${seed.introAngle.ar} تصفح أكثر المسارات صلة في صفحة هبوط واحدة مركزة.`,
|
||||
},
|
||||
introTemplate: {
|
||||
en: seed.introAngle.en,
|
||||
ar: seed.introAngle.ar,
|
||||
},
|
||||
targetToolSlugs: seed.targetToolSlugs,
|
||||
faqTemplates: buildCollectionFaqs(seed),
|
||||
relatedCollectionSlugs: seed.relatedCollectionSlugs,
|
||||
contentSections: buildCollectionSections(seed),
|
||||
}));
|
||||
|
||||
export const SEO_TOTAL_PAGE_COUNT = PROGRAMMATIC_TOOL_PAGES.length + SEO_COLLECTION_PAGES.length;
|
||||
|
||||
export function getLocalizedSeoLandingPaths(locale: SeoLocale): string[] {
|
||||
const prefix = locale === 'ar' ? '/ar' : '';
|
||||
return [
|
||||
...PROGRAMMATIC_TOOL_PAGES.map((page) => `${prefix}/${page.slug}`),
|
||||
...SEO_COLLECTION_PAGES.map((page) => `${prefix}/${page.slug}`),
|
||||
];
|
||||
}
|
||||
Reference in New Issue
Block a user