footer-bottom.php

I’ll make a complete footer-bottom.php template part that works safely in WordPress, includes many footer features, and stays theme-friendly with hooks, schema, menus, copyright, socials, back-to-top, and optional performance helpers.

Below is an advanced, big, safe, and flexible file for:

rx-theme/template-parts/footer/footer-bottom.php

It includes many possible footer-bottom features: copyright, dynamic year, site info, footer menu, social links, back-to-top button, schema JSON-LD, privacy/terms links, accessibility skip link target, scroll progress, reading progress support, performance-safe inline SVG, WordPress hooks, filters, fallback functions, and many customization options.

<?php
/**
 * Template Part: Footer Bottom
 *
 * Path: template-parts/footer/footer-bottom.php
 *
 * @package RxTheme
 * @since 1.0.0
 *
 * This file controls the bottom area of the website footer.
 * It is built with safe WordPress escaping, theme hooks, filters,
 * accessibility support, footer menu support, social links support,
 * schema markup, back-to-top button, and developer-friendly extension points.
 */

defined( 'ABSPATH' ) || exit;

/**
 * ------------------------------------------------------------
 * Helper: Safe function fallback
 * ------------------------------------------------------------
 */

if ( ! function_exists( 'rx_theme_get_option' ) ) {
	/**
	 * Get theme option with fallback.
	 *
	 * You can later replace this with your own Customizer/Redux/ACF option function.
	 *
	 * @param string $key     Option key.
	 * @param mixed  $default Default value.
	 * @return mixed
	 */
	function rx_theme_get_option( $key, $default = '' ) {
		$value = get_theme_mod( $key, $default );

		if ( '' === $value || null === $value ) {
			return $default;
		}

		return $value;
	}
}

if ( ! function_exists( 'rx_theme_current_year' ) ) {
	/**
	 * Return current year.
	 *
	 * @return string
	 */
	function rx_theme_current_year() {
		return esc_html( date_i18n( 'Y' ) );
	}
}

if ( ! function_exists( 'rx_theme_site_name' ) ) {
	/**
	 * Return safe site name.
	 *
	 * @return string
	 */
	function rx_theme_site_name() {
		return esc_html( get_bloginfo( 'name' ) );
	}
}

if ( ! function_exists( 'rx_theme_home_url' ) ) {
	/**
	 * Return home URL.
	 *
	 * @return string
	 */
	function rx_theme_home_url() {
		return esc_url( home_url( '/' ) );
	}
}

if ( ! function_exists( 'rx_theme_footer_bottom_classes' ) ) {
	/**
	 * Footer bottom wrapper classes.
	 *
	 * @return string
	 */
	function rx_theme_footer_bottom_classes() {
		$classes = array(
			'rx-footer-bottom',
			'rx-site-footer-bottom',
			'rx-footer-bottom--advanced',
		);

		if ( is_front_page() ) {
			$classes[] = 'rx-footer-bottom--front-page';
		}

		if ( is_single() ) {
			$classes[] = 'rx-footer-bottom--single';
		}

		if ( is_page() ) {
			$classes[] = 'rx-footer-bottom--page';
		}

		if ( is_user_logged_in() ) {
			$classes[] = 'rx-footer-bottom--logged-in';
		}

		$classes = apply_filters( 'rx_theme_footer_bottom_classes', $classes );

		return esc_attr( implode( ' ', array_unique( array_filter( $classes ) ) ) );
	}
}

if ( ! function_exists( 'rx_theme_get_privacy_policy_link' ) ) {
	/**
	 * Return privacy policy link.
	 *
	 * @return string
	 */
	function rx_theme_get_privacy_policy_link() {
		$privacy_url = get_privacy_policy_url();

		if ( empty( $privacy_url ) ) {
			return '';
		}

		return sprintf(
			'<a class="rx-footer-bottom__link rx-footer-bottom__privacy-link" href="%1$s">%2$s</a>',
			esc_url( $privacy_url ),
			esc_html__( 'Privacy Policy', 'rx-theme' )
		);
	}
}

if ( ! function_exists( 'rx_theme_get_terms_link' ) ) {
	/**
	 * Return terms link from theme option.
	 *
	 * @return string
	 */
	function rx_theme_get_terms_link() {
		$terms_url = rx_theme_get_option( 'rx_terms_url', '' );

		if ( empty( $terms_url ) ) {
			return '';
		}

		return sprintf(
			'<a class="rx-footer-bottom__link rx-footer-bottom__terms-link" href="%1$s">%2$s</a>',
			esc_url( $terms_url ),
			esc_html__( 'Terms & Conditions', 'rx-theme' )
		);
	}
}

if ( ! function_exists( 'rx_theme_get_contact_link' ) ) {
	/**
	 * Return contact link from theme option.
	 *
	 * @return string
	 */
	function rx_theme_get_contact_link() {
		$contact_url = rx_theme_get_option( 'rx_contact_url', '' );

		if ( empty( $contact_url ) ) {
			$contact_page = get_page_by_path( 'contact' );

			if ( $contact_page ) {
				$contact_url = get_permalink( $contact_page );
			}
		}

		if ( empty( $contact_url ) ) {
			return '';
		}

		return sprintf(
			'<a class="rx-footer-bottom__link rx-footer-bottom__contact-link" href="%1$s">%2$s</a>',
			esc_url( $contact_url ),
			esc_html__( 'Contact', 'rx-theme' )
		);
	}
}

if ( ! function_exists( 'rx_theme_get_sitemap_link' ) ) {
	/**
	 * Return sitemap link.
	 *
	 * @return string
	 */
	function rx_theme_get_sitemap_link() {
		$sitemap_url = home_url( '/sitemap.xml' );

		return sprintf(
			'<a class="rx-footer-bottom__link rx-footer-bottom__sitemap-link" href="%1$s">%2$s</a>',
			esc_url( $sitemap_url ),
			esc_html__( 'Sitemap', 'rx-theme' )
		);
	}
}

if ( ! function_exists( 'rx_theme_footer_social_links' ) ) {
	/**
	 * Footer social links.
	 *
	 * Add URLs from Customizer later:
	 * rx_facebook_url, rx_x_url, rx_linkedin_url, rx_youtube_url, etc.
	 *
	 * @return array
	 */
	function rx_theme_footer_social_links() {
		$socials = array(
			'facebook'  => array(
				'label' => __( 'Facebook', 'rx-theme' ),
				'url'   => rx_theme_get_option( 'rx_facebook_url', '' ),
				'icon'  => 'facebook',
			),
			'x'         => array(
				'label' => __( 'X', 'rx-theme' ),
				'url'   => rx_theme_get_option( 'rx_x_url', '' ),
				'icon'  => 'x',
			),
			'linkedin'  => array(
				'label' => __( 'LinkedIn', 'rx-theme' ),
				'url'   => rx_theme_get_option( 'rx_linkedin_url', '' ),
				'icon'  => 'linkedin',
			),
			'youtube'   => array(
				'label' => __( 'YouTube', 'rx-theme' ),
				'url'   => rx_theme_get_option( 'rx_youtube_url', '' ),
				'icon'  => 'youtube',
			),
			'instagram' => array(
				'label' => __( 'Instagram', 'rx-theme' ),
				'url'   => rx_theme_get_option( 'rx_instagram_url', '' ),
				'icon'  => 'instagram',
			),
			'github'    => array(
				'label' => __( 'GitHub', 'rx-theme' ),
				'url'   => rx_theme_get_option( 'rx_github_url', '' ),
				'icon'  => 'github',
			),
			'telegram'  => array(
				'label' => __( 'Telegram', 'rx-theme' ),
				'url'   => rx_theme_get_option( 'rx_telegram_url', '' ),
				'icon'  => 'telegram',
			),
			'whatsapp'  => array(
				'label' => __( 'WhatsApp', 'rx-theme' ),
				'url'   => rx_theme_get_option( 'rx_whatsapp_url', '' ),
				'icon'  => 'whatsapp',
			),
		);

		return apply_filters( 'rx_theme_footer_social_links', $socials );
	}
}

if ( ! function_exists( 'rx_theme_footer_icon' ) ) {
	/**
	 * Return inline SVG icon.
	 *
	 * @param string $icon Icon name.
	 * @return string
	 */
	function rx_theme_footer_icon( $icon = '' ) {
		$icon = sanitize_key( $icon );

		$icons = array(
			'facebook'  => '<svg aria-hidden="true" viewBox="0 0 24 24" width="18" height="18" focusable="false"><path fill="currentColor" d="M22 12a10 10 0 1 0-11.6 9.9v-7h-2.5V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.2c-1.2 0-1.6.8-1.6 1.5V12h2.8l-.4 2.9h-2.4v7A10 10 0 0 0 22 12z"/></svg>',
			'x'         => '<svg aria-hidden="true" viewBox="0 0 24 24" width="18" height="18" focusable="false"><path fill="currentColor" d="M18.9 2h3.4l-7.5 8.6L23.6 22h-6.9l-5.4-7-6.2 7H1.7l8-9.1L1.2 2h7.1l4.9 6.5L18.9 2zm-1.2 18h1.9L7.3 3.9h-2L17.7 20z"/></svg>',
			'linkedin'  => '<svg aria-hidden="true" viewBox="0 0 24 24" width="18" height="18" focusable="false"><path fill="currentColor" d="M4.98 3.5a2.5 2.5 0 1 1 0 5 2.5 2.5 0 0 1 0-5zM3 9h4v12H3V9zm7 0h3.8v1.6h.1c.5-1 1.8-2 3.8-2 4 0 4.8 2.6 4.8 6V21h-4v-5.7c0-1.4 0-3.1-1.9-3.1s-2.2 1.5-2.2 3V21h-4V9z"/></svg>',
			'youtube'   => '<svg aria-hidden="true" viewBox="0 0 24 24" width="18" height="18" focusable="false"><path fill="currentColor" d="M23.5 6.2s-.2-1.7-.9-2.4c-.9-.9-1.9-.9-2.4-1C16.9 2.5 12 2.5 12 2.5s-4.9 0-8.2.3c-.5.1-1.5.1-2.4 1C.7 4.5.5 6.2.5 6.2S.2 8.1.2 10v1.8c0 1.9.3 3.8.3 3.8s.2 1.7.9 2.4c.9.9 2.1.9 2.6 1 1.9.2 8 .3 8 .3s4.9 0 8.2-.3c.5-.1 1.5-.1 2.4-1 .7-.7.9-2.4.9-2.4s.3-1.9.3-3.8V10c0-1.9-.3-3.8-.3-3.8zM9.8 14.6V7.9l6.3 3.4-6.3 3.3z"/></svg>',
			'instagram' => '<svg aria-hidden="true" viewBox="0 0 24 24" width="18" height="18" focusable="false"><path fill="currentColor" d="M7 2h10a5 5 0 0 1 5 5v10a5 5 0 0 1-5 5H7a5 5 0 0 1-5-5V7a5 5 0 0 1 5-5zm10 2H7a3 3 0 0 0-3 3v10a3 3 0 0 0 3 3h10a3 3 0 0 0 3-3V7a3 3 0 0 0-3-3zm-5 3.5A4.5 4.5 0 1 1 12 16.5 4.5 4.5 0 0 1 12 7.5zm0 2A2.5 2.5 0 1 0 12 14.5 2.5 2.5 0 0 0 12 9.5zM17.8 6.2a1 1 0 1 1-1 1 1 1 0 0 1 1-1z"/></svg>',
			'github'    => '<svg aria-hidden="true" viewBox="0 0 24 24" width="18" height="18" focusable="false"><path fill="currentColor" d="M12 .5a12 12 0 0 0-3.8 23.4c.6.1.8-.3.8-.6v-2.1c-3.3.7-4-1.4-4-1.4-.5-1.3-1.3-1.7-1.3-1.7-1.1-.7.1-.7.1-.7 1.2.1 1.9 1.2 1.9 1.2 1.1 1.9 2.9 1.3 3.5 1 .1-.8.4-1.3.8-1.6-2.6-.3-5.4-1.3-5.4-5.8 0-1.3.5-2.3 1.2-3.2-.1-.3-.5-1.5.1-3.1 0 0 1-.3 3.3 1.2a11.4 11.4 0 0 1 6 0C17.6 5.6 18.6 6 18.6 6c.6 1.6.2 2.8.1 3.1.8.9 1.2 1.9 1.2 3.2 0 4.5-2.8 5.5-5.4 5.8.4.4.8 1.1.8 2.2v3.2c0 .3.2.7.8.6A12 12 0 0 0 12 .5z"/></svg>',
			'telegram'  => '<svg aria-hidden="true" viewBox="0 0 24 24" width="18" height="18" focusable="false"><path fill="currentColor" d="M22 3.5 18.6 21c-.3 1.2-1 1.5-2 .9l-5.5-4-2.7 2.6c-.3.3-.5.5-1.1.5l.4-5.6L18 6.2c.5-.4-.1-.6-.7-.2L4.6 14 .1 12.6c-1-.3-1-1 .2-1.5L20.7 3c.9-.4 1.7.2 1.3.5z"/></svg>',
			'whatsapp'  => '<svg aria-hidden="true" viewBox="0 0 24 24" width="18" height="18" focusable="false"><path fill="currentColor" d="M20.5 3.5A11.8 11.8 0 0 0 2.2 17.7L1 23l5.4-1.4A11.8 11.8 0 0 0 12 23a11.8 11.8 0 0 0 8.5-19.5zM12 21a9.7 9.7 0 0 1-5-1.4l-.4-.2-3.2.8.9-3.1-.2-.4A9.8 9.8 0 1 1 12 21zm5.4-7.3c-.3-.1-1.7-.8-1.9-.9-.3-.1-.5-.1-.7.1-.2.3-.8.9-.9 1.1-.2.2-.3.2-.6.1a8 8 0 0 1-2.3-1.4 8.5 8.5 0 0 1-1.6-2c-.2-.3 0-.5.1-.6l.5-.6.2-.5c.1-.2 0-.4 0-.5l-.9-2c-.2-.5-.5-.5-.7-.5H8c-.2 0-.5.1-.8.4s-1 1-1 2.4 1 2.8 1.2 3a11.2 11.2 0 0 0 4.3 3.8c.6.3 1.1.4 1.5.6.6.2 1.2.2 1.6.1.5-.1 1.7-.7 1.9-1.3.2-.7.2-1.2.1-1.3-.1-.2-.2-.2-.5-.4z"/></svg>',
			'arrow-up'  => '<svg aria-hidden="true" viewBox="0 0 24 24" width="20" height="20" focusable="false"><path fill="currentColor" d="M12 4 4 12l1.4 1.4L11 7.8V20h2V7.8l5.6 5.6L20 12z"/></svg>',
			'heart'     => '<svg aria-hidden="true" viewBox="0 0 24 24" width="15" height="15" focusable="false"><path fill="currentColor" d="M12 21s-7.5-4.7-10-9.3C-.3 7.5 2.3 3 6.8 3c2.1 0 4 1.1 5.2 2.8C13.2 4.1 15.1 3 17.2 3c4.5 0 7.1 4.5 4.8 8.7C19.5 16.3 12 21 12 21z"/></svg>',
		);

		$icons = apply_filters( 'rx_theme_footer_icons', $icons );

		return isset( $icons[ $icon ] ) ? $icons[ $icon ] : '';
	}
}

if ( ! function_exists( 'rx_theme_render_footer_social_links' ) ) {
	/**
	 * Render footer social links.
	 *
	 * @return void
	 */
	function rx_theme_render_footer_social_links() {
		$socials = rx_theme_footer_social_links();
		$has_social = false;

		foreach ( $socials as $social ) {
			if ( ! empty( $social['url'] ) ) {
				$has_social = true;
				break;
			}
		}

		if ( ! $has_social ) {
			return;
		}
		?>
		<nav class="rx-footer-bottom__social" aria-label="<?php esc_attr_e( 'Footer social links', 'rx-theme' ); ?>">
			<ul class="rx-footer-bottom__social-list">
				<?php foreach ( $socials as $key => $social ) : ?>
					<?php
					if ( empty( $social['url'] ) ) {
						continue;
					}

					$label = isset( $social['label'] ) ? $social['label'] : ucfirst( $key );
					$icon  = isset( $social['icon'] ) ? $social['icon'] : $key;
					?>
					<li class="rx-footer-bottom__social-item rx-footer-bottom__social-item--<?php echo esc_attr( sanitize_html_class( $key ) ); ?>">
						<a
							class="rx-footer-bottom__social-link"
							href="<?php echo esc_url( $social['url'] ); ?>"
							target="_blank"
							rel="noopener noreferrer nofollow"
							aria-label="<?php echo esc_attr( $label ); ?>"
						>
							<span class="rx-footer-bottom__social-icon">
								<?php echo rx_theme_footer_icon( $icon ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
							</span>
							<span class="screen-reader-text"><?php echo esc_html( $label ); ?></span>
						</a>
					</li>
				<?php endforeach; ?>
			</ul>
		</nav>
		<?php
	}
}

if ( ! function_exists( 'rx_theme_footer_bottom_schema' ) ) {
	/**
	 * Render footer organization schema.
	 *
	 * @return void
	 */
	function rx_theme_footer_bottom_schema() {
		if ( is_admin() ) {
			return;
		}

		$enable_schema = (bool) apply_filters( 'rx_theme_enable_footer_schema', true );

		if ( ! $enable_schema ) {
			return;
		}

		$logo_id  = get_theme_mod( 'custom_logo' );
		$logo_url = '';

		if ( $logo_id ) {
			$logo_url = wp_get_attachment_image_url( $logo_id, 'full' );
		}

		$same_as = array();

		foreach ( rx_theme_footer_social_links() as $social ) {
			if ( ! empty( $social['url'] ) ) {
				$same_as[] = esc_url_raw( $social['url'] );
			}
		}

		$schema = array(
			'@context' => 'https://schema.org',
			'@type'    => 'Organization',
			'name'     => get_bloginfo( 'name' ),
			'url'      => home_url( '/' ),
		);

		if ( ! empty( $logo_url ) ) {
			$schema['logo'] = esc_url_raw( $logo_url );
		}

		if ( ! empty( $same_as ) ) {
			$schema['sameAs'] = array_values( array_unique( $same_as ) );
		}

		$schema = apply_filters( 'rx_theme_footer_bottom_schema', $schema );

		if ( empty( $schema ) || ! is_array( $schema ) ) {
			return;
		}
		?>
		<script type="application/ld+json" class="rx-footer-bottom-schema">
			<?php echo wp_json_encode( $schema, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT ); ?>
		</script>
		<?php
	}
}

/**
 * ------------------------------------------------------------
 * Footer bottom settings
 * ------------------------------------------------------------
 */

$rx_footer_bottom_enable = (bool) apply_filters(
	'rx_theme_enable_footer_bottom',
	rx_theme_get_option( 'rx_enable_footer_bottom', true )
);

if ( ! $rx_footer_bottom_enable ) {
	return;
}

$rx_footer_text = rx_theme_get_option(
	'rx_footer_bottom_text',
	sprintf(
		/* translators: 1: Year, 2: Site name. */
		__( 'Copyright © %1$s %2$s. All rights reserved.', 'rx-theme' ),
		rx_theme_current_year(),
		rx_theme_site_name()
	)
);

$rx_footer_credit_enable = (bool) apply_filters(
	'rx_theme_enable_footer_credit',
	rx_theme_get_option( 'rx_enable_footer_credit', true )
);

$rx_back_to_top_enable = (bool) apply_filters(
	'rx_theme_enable_back_to_top',
	rx_theme_get_option( 'rx_enable_back_to_top', true )
);

$rx_footer_schema_enable = (bool) apply_filters(
	'rx_theme_enable_footer_schema_output',
	rx_theme_get_option( 'rx_enable_footer_schema', true )
);

$rx_footer_extra_links = array_filter(
	array(
		rx_theme_get_privacy_policy_link(),
		rx_theme_get_terms_link(),
		rx_theme_get_contact_link(),
		rx_theme_get_sitemap_link(),
	)
);

$rx_footer_extra_links = apply_filters( 'rx_theme_footer_bottom_extra_links', $rx_footer_extra_links );

?>

<?php do_action( 'rx_theme_before_footer_bottom' ); ?>

<div class="<?php echo rx_theme_footer_bottom_classes(); ?>" role="contentinfo">
	<div class="rx-container rx-footer-bottom__container">

		<?php do_action( 'rx_theme_footer_bottom_start' ); ?>

		<div class="rx-footer-bottom__grid">

			<div class="rx-footer-bottom__left">
				<div class="rx-footer-bottom__copyright">
					<?php
					echo wp_kses_post(
						apply_filters(
							'rx_theme_footer_bottom_text',
							$rx_footer_text
						)
					);
					?>
				</div>

				<?php if ( $rx_footer_credit_enable ) : ?>
					<div class="rx-footer-bottom__credit">
						<?php
						printf(
							wp_kses(
								/* translators: 1: heart icon, 2: site URL, 3: site name. */
								__( 'Made with %1$s by <a href="%2$s">%3$s</a>.', 'rx-theme' ),
								array(
									'a' => array(
										'href'   => array(),
										'target' => array(),
										'rel'    => array(),
										'class'  => array(),
									),
									'span' => array(
										'class' => array(),
									),
									'svg' => array(
										'aria-hidden' => array(),
										'viewBox'     => array(),
										'width'       => array(),
										'height'      => array(),
										'focusable'   => array(),
									),
									'path' => array(
										'fill' => array(),
										'd'    => array(),
									),
								)
							),
							'<span class="rx-footer-bottom__heart">' . rx_theme_footer_icon( 'heart' ) . '</span>',
							esc_url( home_url( '/' ) ),
							esc_html( get_bloginfo( 'name' ) )
						);
						?>
					</div>
				<?php endif; ?>
			</div>

			<div class="rx-footer-bottom__center">
				<?php if ( has_nav_menu( 'footer-bottom' ) ) : ?>
					<nav class="rx-footer-bottom__menu" aria-label="<?php esc_attr_e( 'Footer bottom menu', 'rx-theme' ); ?>">
						<?php
						wp_nav_menu(
							array(
								'theme_location'  => 'footer-bottom',
								'menu_class'      => 'rx-footer-bottom__menu-list',
								'container'       => false,
								'depth'           => 1,
								'fallback_cb'     => false,
								'link_before'     => '<span>',
								'link_after'      => '</span>',
								'item_spacing'    => 'discard',
							)
						);
						?>
					</nav>
				<?php elseif ( ! empty( $rx_footer_extra_links ) ) : ?>
					<nav class="rx-footer-bottom__links" aria-label="<?php esc_attr_e( 'Footer useful links', 'rx-theme' ); ?>">
						<ul class="rx-footer-bottom__links-list">
							<?php foreach ( $rx_footer_extra_links as $rx_footer_link ) : ?>
								<li class="rx-footer-bottom__links-item">
									<?php echo wp_kses_post( $rx_footer_link ); ?>
								</li>
							<?php endforeach; ?>
						</ul>
					</nav>
				<?php endif; ?>
			</div>

			<div class="rx-footer-bottom__right">
				<?php rx_theme_render_footer_social_links(); ?>
			</div>

		</div>

		<?php do_action( 'rx_theme_footer_bottom_end' ); ?>

	</div>
</div>

<?php if ( $rx_back_to_top_enable ) : ?>
	<button
		type="button"
		class="rx-back-to-top"
		id="rxBackToTop"
		aria-label="<?php esc_attr_e( 'Back to top', 'rx-theme' ); ?>"
		hidden
	>
		<span class="rx-back-to-top__icon">
			<?php echo rx_theme_footer_icon( 'arrow-up' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
		</span>
		<span class="screen-reader-text"><?php esc_html_e( 'Back to top', 'rx-theme' ); ?></span>
	</button>
<?php endif; ?>

<div class="rx-scroll-progress" id="rxScrollProgress" aria-hidden="true">
	<span class="rx-scroll-progress__bar" id="rxScrollProgressBar"></span>
</div>

<?php
if ( $rx_footer_schema_enable ) {
	rx_theme_footer_bottom_schema();
}
?>

<script>
(function () {
	'use strict';

	var doc = document;
	var win = window;
	var backToTop = doc.getElementById('rxBackToTop');
	var progress = doc.getElementById('rxScrollProgressBar');

	function getScrollTop() {
		return win.pageYOffset || doc.documentElement.scrollTop || doc.body.scrollTop || 0;
	}

	function getDocumentHeight() {
		var body = doc.body;
		var html = doc.documentElement;

		return Math.max(
			body.scrollHeight,
			body.offsetHeight,
			html.clientHeight,
			html.scrollHeight,
			html.offsetHeight
		);
	}

	function updateBackToTop() {
		if (!backToTop) {
			return;
		}

		if (getScrollTop() > 350) {
			backToTop.hidden = false;
			backToTop.classList.add('is-visible');
		} else {
			backToTop.classList.remove('is-visible');
			backToTop.hidden = true;
		}
	}

	function updateScrollProgress() {
		if (!progress) {
			return;
		}

		var scrollTop = getScrollTop();
		var height = getDocumentHeight() - win.innerHeight;
		var percentage = height > 0 ? (scrollTop / height) * 100 : 0;

		progress.style.width = Math.min(100, Math.max(0, percentage)) + '%';
	}

	function onScroll() {
		updateBackToTop();
		updateScrollProgress();
	}

	if (backToTop) {
		backToTop.addEventListener('click', function () {
			win.scrollTo({
				top: 0,
				behavior: 'smooth'
			});
		});
	}

	win.addEventListener('scroll', onScroll, { passive: true });
	win.addEventListener('resize', updateScrollProgress);

	doc.addEventListener('DOMContentLoaded', function () {
		updateBackToTop();
		updateScrollProgress();
	});
})();
</script>

<?php do_action( 'rx_theme_after_footer_bottom' ); ?>

Add this menu registration in your inc/core/menus.php or functions.php:

<?php
/**
 * Register footer bottom menu.
 */

defined( 'ABSPATH' ) || exit;

add_action( 'after_setup_theme', 'rx_theme_register_footer_bottom_menu' );

if ( ! function_exists( 'rx_theme_register_footer_bottom_menu' ) ) {
	function rx_theme_register_footer_bottom_menu() {
		register_nav_menus(
			array(
				'footer-bottom' => esc_html__( 'Footer Bottom Menu', 'rx-theme' ),
			)
		);
	}
}

Add this CSS in your main CSS file, for example:

assets/css/footer.css

.rx-footer-bottom {
	border-top: 1px solid rgba(15, 23, 42, 0.08);
	background: var(--rx-footer-bottom-bg, #ffffff);
	color: var(--rx-footer-bottom-color, #334155);
	font-size: 14px;
	line-height: 1.7;
}

.rx-footer-bottom__container {
	max-width: var(--rx-container-width, 1200px);
	margin-inline: auto;
	padding: 18px 20px;
}

.rx-footer-bottom__grid {
	display: grid;
	grid-template-columns: 1fr auto 1fr;
	gap: 20px;
	align-items: center;
}

.rx-footer-bottom__left {
	text-align: left;
}

.rx-footer-bottom__center {
	text-align: center;
}

.rx-footer-bottom__right {
	display: flex;
	justify-content: flex-end;
}

.rx-footer-bottom__copyright,
.rx-footer-bottom__credit {
	margin: 0;
}

.rx-footer-bottom__credit {
	font-size: 13px;
	opacity: 0.82;
}

.rx-footer-bottom__heart {
	display: inline-flex;
	vertical-align: -2px;
	color: #e11d48;
}

.rx-footer-bottom a {
	color: inherit;
	text-decoration: none;
}

.rx-footer-bottom a:hover,
.rx-footer-bottom a:focus {
	color: var(--rx-primary-color, #2563eb);
	text-decoration: underline;
}

.rx-footer-bottom__menu-list,
.rx-footer-bottom__links-list,
.rx-footer-bottom__social-list {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 10px 16px;
	margin: 0;
	padding: 0;
	list-style: none;
}

.rx-footer-bottom__menu-list {
	justify-content: center;
}

.rx-footer-bottom__links-list {
	justify-content: center;
}

.rx-footer-bottom__social-list {
	justify-content: flex-end;
}

.rx-footer-bottom__social-link {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 34px;
	height: 34px;
	border-radius: 999px;
	background: rgba(15, 23, 42, 0.06);
	color: currentColor;
	transition: transform 0.2s ease, background-color 0.2s ease, color 0.2s ease;
}

.rx-footer-bottom__social-link:hover,
.rx-footer-bottom__social-link:focus {
	transform: translateY(-2px);
	background: var(--rx-primary-color, #2563eb);
	color: #ffffff;
	text-decoration: none;
}

.rx-back-to-top {
	position: fixed;
	right: 20px;
	bottom: 22px;
	z-index: 999;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	border: 0;
	border-radius: 999px;
	background: var(--rx-primary-color, #2563eb);
	color: #ffffff;
	box-shadow: 0 10px 25px rgba(15, 23, 42, 0.18);
	cursor: pointer;
	opacity: 0;
	visibility: hidden;
	transform: translateY(12px);
	transition: opacity 0.2s ease, visibility 0.2s ease, transform 0.2s ease;
}

.rx-back-to-top.is-visible {
	opacity: 1;
	visibility: visible;
	transform: translateY(0);
}

.rx-back-to-top:hover,
.rx-back-to-top:focus {
	background: var(--rx-primary-hover-color, #1d4ed8);
}

.rx-scroll-progress {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	z-index: 9999;
	height: 3px;
	pointer-events: none;
	background: transparent;
}

.rx-scroll-progress__bar {
	display: block;
	width: 0;
	height: 100%;
	background: var(--rx-primary-color, #2563eb);
	transition: width 0.05s linear;
}

.screen-reader-text {
	position: absolute !important;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

@media (max-width: 768px) {
	.rx-footer-bottom__grid {
		grid-template-columns: 1fr;
		text-align: center;
	}

	.rx-footer-bottom__left,
	.rx-footer-bottom__center,
	.rx-footer-bottom__right {
		text-align: center;
		justify-content: center;
	}

	.rx-footer-bottom__social-list,
	.rx-footer-bottom__menu-list,
	.rx-footer-bottom__links-list {
		justify-content: center;
	}
}

Then call this file from your main footer.php:

<?php
/**
 * Footer template.
 *
 * @package RxTheme
 */

defined( 'ABSPATH' ) || exit;
?>

		<?php do_action( 'rx_theme_before_footer' ); ?>

		<footer id="colophon" class="site-footer rx-site-footer">
			<?php
			get_template_part( 'template-parts/footer/footer-widgets' );
			get_template_part( 'template-parts/footer/footer-bottom' );
			?>
		</footer>

		<?php do_action( 'rx_theme_after_footer' ); ?>

	</div><!-- #page -->

	<?php wp_footer(); ?>

</body>
</html>

Important: for social links, this file reads these Customizer/theme option keys:

rx_facebook_url
rx_x_url
rx_linkedin_url
rx_youtube_url
rx_instagram_url
rx_github_url
rx_telegram_url
rx_whatsapp_url
rx_terms_url
rx_contact_url
rx_enable_footer_bottom
rx_enable_footer_credit
rx_enable_back_to_top
rx_enable_footer_schema
rx_footer_bottom_text

So later you can create a Customizer file like:

inc/customizer/footer-options.php

and save those fields there.

Leave a Reply

Your email address will not be published. Required fields are marked *