Skip to content

Instantly share code, notes, and snippets.

@Genyus
Created March 4, 2022 21:39
Show Gist options
  • Save Genyus/f9b53cf3f10996b99e1aaf3fa94fb090 to your computer and use it in GitHub Desktop.
Save Genyus/f9b53cf3f10996b99e1aaf3fa94fb090 to your computer and use it in GitHub Desktop.
Fix for broken Elementor landing pages when using custom permalinks (v3.4.3+)
/**
* Fixes landing page 404 when non-standard permalinks are enabled.
*
* @param \WP_Query $query
*/
function elementor_pre_get_posts( \WP_Query $query ) {
if (
// If the post type includes the Elementor landing page CPT.
class_exists( '\Elementor\Modules\LandingPages\Module' )
&& is_array( $query->get( 'post_type' ) )
&& in_array( \Elementor\Modules\LandingPages\Module::CPT, $query->get( 'post_type' ), true )
// If custom permalinks are enabled.
&& '' !== get_option( 'permalink_structure' )
// If the query is for a front-end page.
&& ( ! is_admin() || wp_doing_ajax() )
&& $query->is_main_query()
// If the query is for a page.
&& isset( $query->query['page'] )
// If the query is not for a static home/blog page.
&& ! is_home()
// If the page name has been set and is not for a path.
&& ! empty( $query->query['pagename'] )
&& false === strpos( $query->query['pagename'], '/' )
// If the name has not already been set.
&& empty( $query->query['name'] ) ) {
$query->set( 'name', $query->query['pagename'] );
}
}
add_action( 'pre_get_posts', 'elementor_pre_get_posts', 100 );
@gbaumbach
Copy link

Gave this a shot and put it in my snippets, unfortunately, no dice. Still getting 404 error. Permalink structure is set to /blog/%postname%/

If I add /blog/ in the address bar before my LP permalink, it works fine. I'm on Elementor 3.16.4

@owenDecorus
Copy link

Nice one, this sorted the problem for me. Thanks a lot!

@Genyus
Copy link
Author

Genyus commented Dec 14, 2023

@gbaumbach Apologies for the late response, but I finally had a chance to look into your issue.

As your permalink structure includes the /blog/ prefix, then requesting a root path URL like /my-landing-page triggers a query looking for a page or attachment matching that slug, which of course doesn't exist and thus returns a 404. This query is executed before the pre_get_posts action fires and I couldn't see any filters that would allow it to be modified.

As far as I can tell, this behaviour isn't the result of any bug, it's just how WP parses URLs. If you need to access a landing page at the root, you'll have to add a custom rewrite rule to redirect requests for your landing page(s) to the correct underlying URL.

HTH

@gbaumbach
Copy link

Thanks for the response--it seems like Elementor is phasing these out. I ended up just creating a custom post-type for landing pages and was able to maneuver around the /blog issue. Thanks again!

@krishnadiamesso
Copy link

@gbaumbach your answer led me to this video. it is the implementation of the custom post-type. i believe it is a nice workaround.
https://youtu.be/NYKhybukUEc?si=MaPPlAeR_7Rr0rDX

@gbaumbach
Copy link

Cool! Yeah, this worked for us, good share @krishnadiamesso

@vladaman
Copy link

It doesn't seem to be working with Polylang plugin & translations

@kat-hello
Copy link

Not sure if anyone else is still having this issue but I got the following to work:

Step 1 - return to standard URL structure

Step 2 - add the following to functions.php - this is for /blog/ to be added before posts only - based on this post: https://wordpress.stackexchange.com/questions/300806/custom-permalink-for-post-only-not-custom-post-types

// Elementor Landing Page Custom URL Structure Fix

/**

  • Add new rewrite rule
    /
    function create_new_url_querystring() {
    add_rewrite_rule(
    'blog/([^/]
    )$',
    'index.php?name=$matches[1]',
    'top'
    );
    add_rewrite_tag('%recipes%','([^/]*)');
    }
    add_action('init', 'create_new_url_querystring', 999 );

/**

  • Modify post link
  • This will print /blog/post-name instead of /post-name
    */
    function append_query_string( $url, $post, $leavename ) {
    if ( $post->post_type == 'post' ) {
    $url = home_url( user_trailingslashit( "blog/$post->post_name" ) );
    }
    return $url;
    }
    add_filter( 'post_link', 'append_query_string', 10, 3 );

/**

  • Redirect all posts to new url
  • If you get error 'Too many redirects' or 'Redirect loop', then delete everything below
    */
    function redirect_old_urls() {
    if ( is_singular('post') ) {
    global $post;
    if ( strpos( $_SERVER['REQUEST_URI'], '/blog/') === false) {
    wp_redirect( home_url( user_trailingslashit( "blog/$post->post_name" ) ), 301 );
    exit();
    }
    }
    }
    add_filter( 'template_redirect', 'redirect_old_urls' );

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment