آیا پیادهسازی SPA با SEO مطلوب امکانپذیر است؟
وقتی صحبت از SPA میشود. همیشه یکسری نگرانیها در رابطه با SEO مطرح میشود. برای تمامی این چالشها راهحلهایی وجود دارد. معمولا اولین چالشی که مطرح میشود رندر سمت سرور یا SSR و لزوم یا عدم لزوم آن است. اما این همهی ماجرا نیست. در این مطلب نمیخواهم به SRR یا موارد دیگر SEO بپردازم. بلکه به ابتدایی ترین بخش SEO یعنی عنوان و متاتگهای صفحات میپردازم. هدف ارائه روشی ساده و کارآمد برای مدیریت عنوان و متاتگها است. مثال ما در فریم ورک React پیادهسازی شده است. بدیهی است که اصول پیشنهادی در سایر فریم ورکها قابل پیادهسازی است.
اما حالا که نامی از SSR آورده شد، گریزی هم به این موضوع میزنم. معتقدم استفاده از SSR انتخاب معقولی است. اما در حال حاضر بیشتر موتورهای جستجو قابلیت اجرا کردن کدهای سمت کاربر را دارند. به گونهای که میتوان با در نظر گرفتن نکاتی از سلامت نسبی ایندکس شدن صفحات اطمینان حاصل نمود. همچنین به کمک ابزار Fetch as Google میتوانید از رندر شدن صحیح صفحات توسط بات گوگل اطمینان حاصل کنید. با در نظر گرفتن این موارد میتوان تا حد خوبی از مزایای SSR در SEO چشم پوشی کرد.
مدیریت عنوان و متاتگها
یکی از نخستین موضوعات مرتبط با SEO که به ذهن میرسد، مدیریت عنوان و متاتگهای صفحات است. چندین چالش در حل این مسئله وجود دارد.
۱. روشی برای مدیریت بخش Header
یک SPA در بخش Body صفحه زندگی میکند. این به این معنی است که از امکانات دسته اول فریم ورک در بخش Header بی بهره هستیم. برای حل این مشکل میتوان از پکیجهای کمکی استفاده نمود یا خودمان یک API مناسب طراحی یا پیاده سازی کنیم. یا ترکیبی از هر دو! من از پکیج React-Helmet برای مثال این مطلب استفاده میکنم.
۲. صفحات با محتوای داینامیک
مساله بعدی که بی ارتباط با مسئله اول نیست. داینامیک بودن اطلاعات عنوان و متاتگهاست. اطلاعاتی که در بطن SPA یا به عبارتی بخش Body موجود است. و نه در بخش Header. برای مثال صفحه محصول یک فروشگاه. این مسئله میتواند به کمک یک API حل شود. این API باید در بخش Body صفحه در دسترس باشد تا بتوان به کمک آن اطلاعات مورد نظر را به بخش Header منتقل نمود.
۳. نگهداری در درازمدت
زمانی با این موضوع روبرو خواهید شد که کار تا حد خوبی پیش رفته و ناگهان متوجه میشوید وضعیت SEO مناسب نیست. عنوان و متاتگهای صفحات محتوای مناسبی ندارند یا به کلی فراموش شدهاند. در این مرحله چارهای ندارید جز این که تک به تک صفحات را بازبینی کنید. علت این موضوع این است که SEO به شکل جزئی کوچک از تک تک صفحات در نظر گرفته شده. این بخش کوچک در جریان توسعه یک صفحه در اولویتهای توسعه دهنده قرار نمیگیرد. چون در کارکرد صفحه تاثیری ندارد و به سادگی فراموش میشود. به عبارتی SEO یک شهروند درجه یک پروژه محسوب نمیشود. علاوه بر آن یک نمای کلی از وضعیت عنوان و متاتگهای صفحات وجود ندارد و باعث بی اطلاعی از وضع موجود میشود. در نظر گرفتن یک بخش مرکزی برای تعریف عنوان و متاتگهای تمام صفحات این مسئله را حل میکند.
راهکار فنی
ماژولی را فرض کنید که به ازاء هر Route متاتگها، عنوان و سایر موارد مربوط به SEO را در صفحه مربوطه ایجاد میکند. با توجه به این که کامپاننت، API درجه یک React محسوب میشود، پس برای پیاده سازی این راهحل یک کامپاننت در نظر میگیریم. این کامپاننت باید بداند Route در حال رندر شدن چیست و چه اطلاعاتی برای رندر عنوان و متاتگها لازم است. نهایتا چه متاتگهایی باید تولید شود. در پایان باید بتواند نتیجه را Header صفحه تزریق کنید.
برای این که کامپاننت ما بداند برای چه صفحهای چه متاتگهایی باید ایجاد شود. یک کانفیگ مرکزی در نظر میگیریم. کانفیگ یا تنظیمات مورد نظر ما میتواند به این صورت باشد که که به ازاء هر Route یک تابع تعریف شود. این تابع props کامپاننت اصلی صفحه را دریافت میکند و یک قطعه JSX یا یک آبجکت تولید میکند. برای ارسال کانفیگها به کامپاننت میتوانیم از ترکیب Context API و/یا HOC استفاده کنیم یا حتی در تعریف کامپاننتمان قرارش بدهیم.
برای ارسال اطلاعات صفحه می توانیم تمامی یا برخی از پراپرتیهای صفحه را به کامپاننت SEO ارسال کنیم. سپس تمام پراپرتیهای ارسال شده به تابعِ کانفیگِ متناظرِ Route جاری ارسال میشود. تا بتواند متاتگها را مطابق کانفیگ انجام شده ایجاد کند.
آخرین مورد تشخیص Route جاری است. در صورتی که از react-router ورژن ۴ استفاده کنیم. نام Route از طریق پراپرتیهای کامپاننت اصلی یا والد در حال رندر در اختیارمان قرار میگیرد. اگر از ورژن ۳ استفاده کنیم باید از ایونت onChange استفاده کنیم و آدرس Route جاری را جایی ذخیره کنیم (مثلا در Redux ؟). آنگاه با استفاده از HOC و/یا Context API (یا Redux ؟) آدرس Route جاری را به کامپاننت SEO بفرستیم.
به این ترتیب شما صاحب یک فایل کانفیگ مرکزی خواهید شد. به کمک این فایل در یک نمای کلی وضعیت متاتگهای سایت شما را نمایش میدهد. یک موجودیت درجه یک در پروژه با قابلیت نظارت و کنترل. دیگر نیازی نیست تک به تک صفحات را بررسی کنید. هر آنچه نیاز است در یک جا قرار دارد. در پروژههای بزرگ می توانید کانفیگها را بر اساس ماژولها دسته بندی کنید. شاید بتوانیم کاری کنیم که نیاز به درج کامپاننت SEO در همه صفحات نباشد!
نکته، متمرکز شدن خود یک anti pattern است و مشکلاتی به همراه دارد. مثلا به وجود آمدن dead code در دراز مدت. اما بعضی مواقع دوست داریم کل ماجرای مربوط به یک موضوع یک جا باشد. متمرکز سازی کمک میکند بتوانیم یک دید کلی داشته باشیم. هیچ چیز مطلق نیست.
نمونه پیاده سازی شده در ریپازیتوری گیتهاب من در دسترس شما قرار دارد.
مطلب خیلی خوبی بود. از اتفاق همین چند روز پیش داشتم به همین داستان متاتگها فکر میکردم که مطلبتون من رو مقداری زیادی جلو برد …
باعث خوشحالیه.
خیلی ممنون. مطلب خیلی خوبی بود. ولی کاش در قالب مثال مقداری فنی تر واردش میشدید، به طور کلی rep گیتتو رو با جزئیات توضیح میدادید.
خواهش میکنم. بله درسته. در حقیقت به موضوع تنبلی بر میگرده. باید امکان اسنیپت کد نوشتن رو فراهم کنم. این دومین مطلب و اولین مطلب فنی این سایت هست و خب هنوز وضعیت فنی سایت روبه راه نیست.