هوک wp_footer یکی از پرکاربردترین هوک‌های وردپرس برای تزریق اسکریپت، کد رهگیری و کدهای اختصاصی پیش از بسته شدن تگ body است. این هوک پایه عملکرد ابزارهای تحلیلی، اسکریپت‌های تعاملی، پاپ‌آپ‌ها و ویجت‌های چت محسوب می‌شود. استفاده درست از آن، از مسدود شدن رندر HTML، تداخل با افزونه‌های کش و نبود داده تحلیلی جلوگیری می‌کند. اشتباهات رایجی مانند نبود شرط، نبود async، نبود escape و نبود تست می‌تواند سرعت سایت را کاهش دهد یا داده رهگیری را از بین ببرد. تسلط بر این هوک برای قالب‌نویسی و افزونه‌نویسی حرفه‌ای ضروری است و در عملکرد سایت کاربرد جدی دارد.

چرا هوک wp_footer نقطه حیاتی عملکرد سایت است؟

بخش انتهایی صفحه HTML، پیش از بستن تگ body، نقطه ایده‌آل برای بارگذاری اسکریپت‌هایی است که به DOM وابسته هستند اما در ابتدای رندر نیاز نیستند. این رویکرد که به آن Deferred Loading گفته می‌شود، سرعت بارگذاری اولیه سایت را افزایش می‌دهد. ابزارهای تحلیلی مانند Google Analytics، ویجت‌های چت، پاپ‌آپ‌ها و اسکریپت‌های تعاملی معمولاً در این نقطه بارگذاری می‌شوند. اگر هوک wp_footer در قالب فراخوانی نشود، این ابزارها کار نمی‌کنند و داده تحلیلی جمع‌آوری نمی‌شود.

هوک wp_footer چیست؟

هوک wp_footer یک اکشن هوک در هسته وردپرس است که در فایل footer.php قالب، پیش از بستن تگ </body>، فراخوانی می‌شود. تمام افزونه‌ها و کدهایی که به این هوک متصل هستند، در این نقطه کد خود را در HTML تزریق می‌کنند. نکته مهم این است که اگر قالب شما تابع wp_footer() را فراخوانی نکند، ابزارهایی مانند Google Analytics، Facebook Pixel، ویجت‌های چت و بسیاری از افزونه‌ها کار نمی‌کنند. این مسئله در قالب‌های سفارشی و آماتور رایج است.

ساختار و پارامترها

ساختار پایه اتصال به این هوک:
add_action( 'wp_footer', 'mytheme_footer_scripts' );
function mytheme_footer_scripts() {
    // تزریق کد در فوتر
}
این هوک هیچ پارامتر ورودی نمی‌گیرد. تمام منطق در بدنه تابع callback اجرا می‌شود. نکته مهم: تابع callback باید در functions.php قالب یا در فایل اصلی افزونه تعریف شود.

نقش priority در ترتیب اجرا

پارامتر دوم add_action، اولویت تابع callback است. مقدار پیش‌فرض ۱۰ است. اولویت تعیین می‌کند که کد شما در چه ترتیبی نسبت به سایر کدها درج شود. کاربردهای رایج اولویت: - اولویت ۱ تا ۵: تزریق کدهای حیاتی که باید ابتدا درج شوند - اولویت ۱۰: ترتیب استاندارد - اولویت ۹۹ یا ۱۰۰: تزریق کدهای نهایی که باید در انتهای فوتر قرار گیرند نمونه:
add_action( 'wp_footer', 'mytheme_chat_widget', 20 );
function mytheme_chat_widget() {
    echo '<script src="https://cdn.example.com/chat.js" async></script>';
}

add_action( 'wp_footer', 'mytheme_analytics', 99 );
function mytheme_analytics() {
    // تزریق کد تحلیلی در انتهای فوتر
}
نکته مهم: اگر می‌خواهید کد شما پس از کدهای افزونه‌های تحلیلی درج شود، از اولویت بالاتر استفاده کنید. برای مطالعه دقیق‌تر درباره هوک‌های مرتبط، به راهنمای هوک wp_head و راهنمای هوک wp_enqueue_scripts مراجعه کنید.

کاربردهای عملی: اسکریپت و رهگیری

تزریق کد Google Analytics:
add_action( 'wp_footer', 'mytheme_ga_code', 10 );
function mytheme_ga_code() {
    $ga_id = get_option( 'mytheme_ga_id' );
    if ( empty( $ga_id ) ) {
        return;
    }
    ?>
    <script async src="https://www.googletagmanager.com/gtag/js?id=<?php echo esc_attr( $ga_id ); ?>"></script>
    <script>
    window.dataLayer = window.dataLayer || [];
    function gtag(){dataLayer.push(arguments);}
    gtag('js', new Date());
    gtag('config', '<?php echo esc_js( $ga_id ); ?>');
    </script>
    <?php
}
تزریق اسکریپت پاپ‌آپ:
add_action( 'wp_footer', 'mytheme_popup_script', 20 );
function mytheme_popup_script() {
    if ( ! is_front_page() ) {
        return;
    }
    echo '<script src="' . esc_url( get_template_directory_uri() . '/assets/js/popup.js' ) . '" defer></script>';
}
تزریق کد سفارشی از تنظیمات قالب:
add_action( 'wp_footer', 'mytheme_custom_footer_code', 50 );
function mytheme_custom_footer_code() {
    $custom_code = get_theme_mod( 'mytheme_footer_code', '' );
    if ( empty( $custom_code ) ) {
        return;
    }
    echo wp_kses_post( $custom_code );
}
نکته مهم: در تزریق کد سفارشی، از wp_kses_post استفاده کنید تا از تزریق کدهای خطرناک جلوگیری شود. راهنمای esc_html در صفحه esc_html آمده است.

کد رهگیری و ابزارهای تحلیلی

ابزارهای تحلیلی و تبلیغاتی مدرن معمولاً از تگ‌های چندگانه استفاده می‌کنند:
add_action( 'wp_footer', 'mytheme_facebook_pixel', 15 );
function mytheme_facebook_pixel() {
    $pixel_id = get_option( 'mytheme_fb_pixel' );
    if ( empty( $pixel_id ) ) {
        return;
    }
    ?>
    <script>
    !function(f,b,e,v,n,t,s){...}(window, document,'script',
    'https://connect.facebook.net/en_US/fbevents.js');
    fbq('init', '<?php echo esc_js( $pixel_id ); ?>');
    fbq('track', 'PageView');
    </script>
    <noscript>
    <img height="1" width="1" style="display:none"
    src="https://www.facebook.com/tr?id=<?php echo esc_attr( $pixel_id ); ?>&ev=PageView&noscript=1">
    </noscript>
    <?php
}
نکته مهم: کدهای رهگیری معمولاً داده حساس کاربر را جمع‌آوری می‌کنند. اگر سایت شما در اروپا فعالیت می‌کند، باید رضایت کاربر (Cookie Consent) را دریافت کنید. برای مطالعه بیشتر درباره رضایت کوکی، به راهنمای GDPR برای فروشگاه و راهنمای Consent Mode مراجعه کنید.

ویجت چت و ابزارهای تعاملی

ویجت‌های چت، پاپ‌آپ‌ها و سایر ابزارهای تعاملی معمولاً از هوک wp_footer استفاده می‌کنند:
add_action( 'wp_footer', 'mytheme_live_chat', 30 );
function mytheme_live_chat() {
    $chat_id = get_option( 'mytheme_chat_id' );
    if ( empty( $chat_id ) ) {
        return;
    }
    ?>
    <script>
    window.$crisp=[];
    window.CRISP_WEBSITE_ID="<?php echo esc_js( $chat_id ); ?>";
    (function(){
        d=document;s=d.createElement("script");
        s.src="https://client.crisp.chat/l.js";
        s.async=1;d.getElementsByTagName("head")[0].appendChild(s);
    })();
    </script>
    <?php
}
نکته مهم: استفاده از async برای اسکریپت‌های چت ضروری است تا رندر HTML مسدود نشود.

نقش در Child Theme

در Child Theme، می‌توانید کد سفارشی خود را به wp_footer اضافه کنید. اما نکته مهم این است که تابع wp_footer() در فایل footer.php قالب Parent فراخوانی می‌شود و اگر فایل فوتر را در Child Theme کپی نکرده باشید، از Parent استفاده می‌شود. الگوی افزودن کد به Child Theme:
add_action( 'wp_footer', 'mychild_footer_scripts', 25 );
function mychild_footer_scripts() {
    if ( ! is_singular( 'post' ) ) {
        return;
    }
    echo '<script src="' . esc_url( get_stylesheet_directory_uri() . '/assets/js/reading-progress.js' ) . '" defer></script>';
}
نکته مهم: اگر قالب Parent از هوک wp_footer استفاده نمی‌کند (که بسیار نادر است)، باید فایل فوتر را در Child Theme کپی و تابع wp_footer() را اضافه کنید. برای مطالعه درباره ساختار Child Theme به راهنمای get_footer مراجعه کنید.

نکات امنیتی و اشتباهات رایج

اشتباه اول، نبود شرط است. اگر کد شما تنها در صفحات خاص نیاز است، از شرط‌هایی مانند is_singular یا is_front_page استفاده کنید. اشتباه دوم، نبود async یا defer است. اسکریپت‌های غیرضروری باید با این استراتژی‌ها بارگذاری شوند تا رندر HTML مسدود نشود. اشتباه سوم، نبود escape در خروجی است. هر داده پویا که در HTML تزریق می‌شود باید با توابع escape عبور کند. اشتباه چهارم، نبود تست است. باید در همه صفحات قالب و دستگاه‌های مختلف بررسی کنید که کدها به‌درستی درج می‌شوند. اشتباه پنجم، نبود توجه به کش است. اگر از افزونه کش استفاده می‌کنید، خروجی wp_footer ممکن است کش شود. باید استراتژی مناسب انتخاب شود. اشتباه ششم، فراموشی فراخوانی wp_footer() در قالب است. اگر این تابع در قالب فراخوانی نشود، ابزارهای تحلیلی و ویجت‌های چت کار نمی‌کنند. اشتباه هفتم، استفاده از handle تکراری است. اگر از wp_enqueue_script استفاده می‌کنید، از پیشوند اختصاصی استفاده کنید.

تحلیل فنی پیشرفته

در نگاه مهندسی، هوک wp_footer یک نقطه معماری در لایه رندر است که بر چند جنبه از سیستم اثر می‌گذارد. لایه اول لایه Performance است. بارگذاری اسکریپت‌ها در فوتر، رندر HTML را مسدود نمی‌کند و سرعت بارگذاری اولیه را افزایش می‌دهد. این الگو در Core Web Vitals تأثیر محسوسی دارد. لایه دوم لایه Defer and Async است. اسکریپت‌های فوتر می‌توانند با defer یا async بارگذاری شوند. defer اسکریپت را پس از تجزیه HTML و به‌ترتیب اجرا می‌کند؛ async اسکریپت را مستقل از سایر اسکریپت‌ها بارگذاری و اجرا می‌کند. لایه سوم لایه امنیت است. تزریق کد در فوتر می‌تواند سطح حمله XSS را افزایش دهد. همیشه از توابع escape استفاده کنید. لایه چهارم لایه Integration است. ابزارهای تحلیلی، ویجت‌های چت، اسکریپت‌های پاپ‌آپ و کتابخانه‌های جاوااسکریپت از این نقطه بارگذاری می‌شوند. لایه پنجم لایه کشینگ است. خروجی wp_footer معمولاً کش می‌شود. اگر خروجی بر اساس وضعیت کاربر تغییر کند، باید استراتژی کش مناسب انتخاب شود. لایه ششم لایه SEO است. اگرچه متا تگ‌های سئو در head هستند، اما اسکریپت‌های داده ساختاریافته گاهی در فوتر بارگذاری می‌شوند. لایه هفتم لایه Multisite است. در شبکه‌های Multisite، هر سایت می‌تواند کد متفاوتی در فوتر داشته باشد. لایه هشتم لایه تست است. تست‌های End-to-End باید مطمئن شوند که کد شما در همه صفحات به‌درستی درج می‌شود. مفاهیم پایه‌ای Deferred Loading در Deferred Loading در ویکی‌پدیا توضیح داده شده است. برای مطالعه بیشتر روی توابع مرتبط، می‌توانید به راهنمای هوک wp_head، راهنمای هوک wp_enqueue_scripts، راهنمای wp_enqueue_script، راهنمای wp_enqueue_style، راهنمای wp_localize_script، راهنمای get_footer، راهنمای GDPR برای فروشگاه و راهنمای Consent Mode مراجعه کنید.

پرسش‌های پرتکرار

تفاوت wp_footer و get_footer چیست؟ اولی یک هوک در داخل فایل فوتر است و دومی فایل فوتر را بارگذاری می‌کند. آیا می‌توان چند بار این هوک را فراخوانی کرد؟ بله، با اولویت‌های مختلف، اما هر کد یک بار اجرا می‌شود. چطور اسکریپت را با async اضافه کنم؟ با wp_enqueue_script و پارامتر strategy => 'async' یا با تزریق مستقیم تگ script با صفت async. آیا این هوک در پنل مدیریت اجرا می‌شود؟ خیر، در پنل از admin_footer استفاده کنید. چطور از تداخل با افزونه‌های کش جلوگیری کنیم؟ با بررسی خروجی نهایی صفحه و تنظیم استراتژی کش مناسب در افزونه کش.

نتیجه و مسیر ادامه

هوک wp_footer نقطه حیاتی تزریق اسکریپت، کد رهگیری و کدهای اختصاصی پیش از بسته شدن body است. استفاده درست از آن یعنی انتخاب priority مناسب، استفاده از async یا defer، escape در خروجی، شرط‌گذاری دقیق و تست در دستگاه‌های مختلف. اشتباه‌های کوچک در این هوک اغلب به نبود داده تحلیلی، کندی سرعت سایت یا تداخل با افزونه‌ها منجر می‌شوند. اگر این هوک را در پروژه‌ای واقعی به کار برده‌اید و رفتار غیرمنتظره‌ای دیده‌اید — به‌خصوص در ترکیب با افزونه‌های کش یا ابزارهای تحلیلی — تجربه‌تان می‌تواند راهگشای دیگران باشد. کدام بخش بیشترین زمان را از شما گرفت؟ دیدگاه خود را بنویسید.