Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Is there an existing solution to add the rel="next" and link rel="prev" to paginated views? It seems to be a best practice suggested by Google for indexing.
I have looked around and cannot find a reference to an existing solution. Any assistance would be appreciated.
Comments
Comment #1
merlinofchaos CreditAttribution: merlinofchaos commentedPresumably you mean the pager links? For the most part that's handled by Drupal's own theme('pager') unless you're using the mini pager, which is theme('views_mini_pager') and can be modified simply by implementing the correct theme function and adding what is needed to the links.
Comment #2
sammyframson CreditAttribution: sammyframson commentedThanks for your prompt reply. I am actually talking about adding the
<link rel="next" a href="/example?page=2">
to the head for SEO purposes as an alternative to the canonical meta data. In reference to the Google Webmaster best practice shown here: http://googlewebmastercentral.blogspot.co.uk/2011/09/pagination-with-rel....Maybe I am asking in the wrong place and this would be more appropriate for a module like nodewords?
Comment #4
MartinSpence CreditAttribution: MartinSpence commentedDid you get sorted with this?
What was the solution?
Thanks
M
Comment #5
Seven_Six_Two CreditAttribution: Seven_Six_Two commentedThere is similar functionality needed for Pagination module, so perhaps this should be done elsewhere? I'm not sure if it merits an individual module, but how about a call to drupal_add_html_head()?
Comment #6
skat CreditAttribution: skat commentedsubscribing
Comment #7
pixelsweatshop CreditAttribution: pixelsweatshop commentedskat use the follow button at the top of the thread to follow issues.
Comment #8
lfboulanger CreditAttribution: lfboulanger commentedI found a way to do it with hook_views_post_execute() :
Comment #9
nlisgo CreditAttribution: nlisgo commentedHere's a solution for D7:
Comment #10
nlisgo CreditAttribution: nlisgo commentedThis is the final solution that I went with. The abstraction of the mymodule_core_set_rel_links and mymodule_core_prep_rel_links makes the code more testable and reusable.
Comment #11
nlisgo CreditAttribution: nlisgo commentedI wanted to see if there was any appetite to take this task. We have some examples of implementations.
Although views is not the only module that uses pagination, it is not the case that we would want the rel links introduced into the head for all paginated content. If for instances the main content of the page is not a listing but there is a block in the sidebar with a pager we would not want that blocks' next and previous links to be considered the next and previous content relevant to this page.
If we have a view that is a page display with pagination then it may be appropriate to assume that we would want the next and previous content to be the pages accessed by the next and previous link of that view.
So, the feature I am proposing is that we automatically introduced the
and
into the head if the view display is page. And we allow the user to deselect this as an option in the pager interface.
For other view displays the default is to have this option deselected and we introduce it if the user makes the decision to select it in the pager interface.
Comment #12
merlinofchaos CreditAttribution: merlinofchaos commentedI think the 'correct' way to do this would be:
1) Implement this as a separate module.
2) Implement a new pager plugin, presumably as a child of views_plugin_pager_full.
3) Handle all of your stuff from within the pager plugin rather than as a views hook.
4) Put your module up in contrib where all can benefit from it if it is a feature they want.
Comment #13
nlisgo CreditAttribution: nlisgo commentedI can't argue with that. It was really only to test the waters. I needed to implement it on our site and the solution in #8 helped me out and it would be a shame if a solution can't be contributed back in some way. The majority of use cases would be in a views pager.
Feel free to close. Happy to contribute as a separate module if no desire to implement it here.
Comment #14
nlisgo CreditAttribution: nlisgo commentedJust rushed together a module that can do what is described in #12. Not sure on the name yet: nextprev_links. Will post module up to d.o. shortly. It's on github for now.
https://github.com/nlisgo/nextprev_links
Comment #15
larsmw CreditAttribution: larsmw commentedThis #14 seems to work nicely. Is there a version here on d.o yet?
Comment #16
nlisgo CreditAttribution: nlisgo commented@larsmw I've posted it as a sandbox project. I'm stalling from posting as a full project until I'm happy with the name of the module. Please give feedback on the module name and anything else.
https://www.drupal.org/sandbox/nlisgo/2361421
Comment #17
bewilled CreditAttribution: bewilled commented#14 didn't work for me for views+search api
Comment #18
heyyo CreditAttribution: heyyo commentedI would like to use your code for an infinite pager provided by views_infinite_scroll or views_show_more.
Any guideline is welcome.
Comment #19
nlisgo CreditAttribution: nlisgo commented@heyyo - if views_infinite_scroll and views_show_more offer their own pager plugins then patches to their module will need to be made to add the option to output the the rel next and prev links. The next step would be to raise an issue on those projects, if one doesn't exist already, to request this enhancement. Add a reference to my sandbox project as a possible solution.
The weakness of the module that I have developed is that it prepares a new pager plugin rather than extend the existing pager plugins to introduce this option. I don't know that this is a possibility, I have an odea of how to make it work but I want to make sure that I do it in the best way possible and it will continue to work well with ctools for exporting and importing views.
This is why I initially proposed that it be added to the views project itself because that seemed to be the approach that made the ux make most sense. You enable my module and you just get new options for pagers.
@bewilled if you could provide more information I could try to off you some support.
Comment #20
tanmoy1981 CreditAttribution: tanmoy1981 as a volunteer commentedI solved this by using theme_pager_link().
Here follows the solution.
Comment #21
flocondetoilesolution in #10 works fine
thanks @nlisgo
Comment #22
cakka CreditAttribution: cakka commentedsolution #10 work good
you only need to write a new module or add the codes to your custom module
Comment #23
tr-drupal CreditAttribution: tr-drupal commentedHi all,
I'm not a drupal developer, so no idea what to do with #10. Is this the latest status of this issue? How far is the sandbox module in #16? Still nothing final / stable?
Comment #24
mgiffordWhy can't this be part of Views? Is there any reason for it to be a module rather than just part?
Just looking for a better explanation for "Closed (won't fix)".
Comment #25
nlisgo CreditAttribution: nlisgo commented@mgifford see #12
Comment #26
vaccinemedia CreditAttribution: vaccinemedia at CTI Digital commented#10 does not work if you have the metatag module installed
Comment #27
phandolin CreditAttribution: phandolin commentedOne more request for this feature. I have metatags installed and cannot get this to work. Thanks!
Comment #28
sagesolutions CreditAttribution: sagesolutions commentedI also have metatags module installed, and this module conflicts with metatags, and doesnt output the head link(s).
Comment #29
vaccinemedia CreditAttribution: vaccinemedia at CTI Digital commentedIf you need prev / next links see this alternative solution: https://www.drupal.org/node/2502453
Comment #30
nlisgo CreditAttribution: nlisgo commentedI will see if I can do an update to that module over the next couple of days so it doesn't conflict with the metatag module :)
Comment #31
nlisgo CreditAttribution: nlisgo commentedIf you are having issues with the nextprev_links module working with metatags module please head over to the following issue to add clear recreate steps and to test a possible fix when I post it up later:
#2613216: Module doesn't work with metatags module enabled
Comment #32
swilmes CreditAttribution: swilmes commentedHi, just wondering if anyone had a way to add the tags rel="next" and rel="prev" tags to search pages? The code above here works great for views but not for searches through the Search API. Thanks!
Comment #33
glass.dimly CreditAttribution: glass.dimly commentedI'm with @mgifford on this. I think this should be a part of Views core because it's a part of Google's official recommendations for pagination.
Source:
I'm therefore re-opening this and classifying as a bug rather than a feature on version 8x where development is more active because as it stands Views pagination is not conformant with Google's SEO best practices. Module maintainers may disagree and change the status of this ticket.
Comment #34
LendudeMoving to the right queue.
Since core doesn't provide any metatags, I'm pretty sure this isn't enough to make this a bug.
Issues I see just from the top of my head:
- Multiple pagers on a single page (multiple Views blocks on a page with a page View! Fun!)
- Ajaxified pagers, what to do? (crawlers with javascript support vs. crawlers without? head doesn't match content after using the pager?)
I would say contrib along the lines of what @nlisgo did in #14/#16 sounds like the way to go to me.
But I can totally see the use cases for this, so lets leave it open as a feature request, who knows....
Comment #35
nlisgo CreditAttribution: nlisgo commentedThanks for this intervention @Lendude. I'm happy for this to live in contrib at present but will propose that it be adopted into core if and when we address some of the issues in your comment. It was really good to meet you at Dev Days last week.
Comment #36
milodescRE #19:
it does.
there is an issue for Views Infinite Scroll here: https://www.drupal.org/node/2283415
Comment #38
TechnoTim2010 CreditAttribution: TechnoTim2010 as a volunteer commentedHi
I took a completely different approach to this, mainly because we need a solution for multiple websites, each built different ways with some pages created in views, some as node listings, some as Taxonomy Term pages and some as Search and Apache Solr search results.
So I created a token that calculates the value for the url part of the metatag link and specifically the page numbers or not for the rel="prev" rel="next" metatags.
This can then be added into to the metatags settings as a token and used as is.
However it does not work on any Taxonomy Term pages and even when overridden by Views, and I have ascertained that the global $pager_total_items and by derivation the $pager_total variables are empty.
I cannot fathom why they are empty and since one site only has Taxonomy term pages as paged pages this is a pain.
When I have it cleaned up will share the code for this token, I think its a cleaner approach, but need a solution for Taxonomy Terms.
regards
Tim
Comment #39
benjen CreditAttribution: benjen commented@TechnoTim2010: Would you please share your solution (even if it still does not support all view types)? I would appreaciate this!
Thank you.
Comment #41
rahul_sankrit CreditAttribution: rahul_sankrit commentedThanks nlisgo , #10 is working good as expected for me.
In my case, I have created a custom module and implemented that code.
Comment #42
DiDebruI achieved this with this hook in D8.2.7
Comment #43
semjuel CreditAttribution: semjuel commentedSolution #42 works great, thanks @Insasse!
Comment #44
burshyn CreditAttribution: burshyn commentedComment #45
burshyn CreditAttribution: burshyn commentedSolution # 10 works fine with drupal 7!
Thanks @nlisgo!
Comment #47
kamy@cool CreditAttribution: kamy@cool commentedI tried #20 but it haven't affected the head section of the page, So I made a bit change in the code and it worked in D7
//implement this hook in template.php
function theme_name_pager_link($variables) {
$text = $variables['text'];
$page_new = $variables['page_new'];
$element = $variables['element'];
$parameters = $variables['parameters'];
$attributes = $variables['attributes'];
$page = isset($_GET['page']) ? $_GET['page'] : '';
if ($new_page = implode(',', pager_load_array($page_new[$element], $element, explode(',', $page)))) {
$parameters['page'] = $new_page;
}
$query = array();
if (count($parameters)) {
$query = drupal_get_query_parameters($parameters, array());
}
if ($query_pager = pager_get_query_parameters()) {
$query = array_merge($query, $query_pager);
}
// Set each pager link title.
if (!isset($attributes['title'])) {
static $titles = NULL;
if (!isset($titles)) {
$titles = array(
t('« first') => t('Go to first page'),
t('‹ previous') => t('Go to previous page'),
t('next ›') => t('Go to next page'),
t('last »') => t('Go to last page'),
);
}
if (isset($titles[$text])) {
$attributes['title'] = $titles[$text];
}
elseif (is_numeric($text)) {
$attributes['title'] = t('Go to page @number', array('@number' => $text));
}
// Add rel attribute.
if ($text == t('‹ previous')) {
$attributes['rel'] = 'prev';
drupal_add_html_head_link(array('rel' => 'prev', 'href' => url($_GET['q'], array('query' => $query))));
}
elseif ($text == t('next ›')) {
$attributes['rel'] = 'next';
drupal_add_html_head_link(array('rel' => 'next', 'href' => url($_GET['q'], array('query' => $query))));
}
}
// @todo l() cannot be used here, since it adds an 'active' class based on the
// path only (which is always the current path for pager links). Apparently,
// none of the pager links is active at any time - but it should still be
// possible to use l() here.
// @see http://drupal.org/node/1410574
$attributes['href'] = url($_GET['q'], array('query' => $query));
return '' . check_plain($text) . '';
}
Comment #48
codechefmarc CreditAttribution: codechefmarc commented#10 works perfectly! Thank you!
Comment #49
Jaesin CreditAttribution: Jaesin at Chapter Three commentedThe following works for me in D8.
Comment #52
nikhileshpaul CreditAttribution: nikhileshpaul commentedSolution #42 works perfectly. Thanks.
For solution #49, @Jaesin can you explain how are you able to get the hook hook_preprocess_pager. I don't think such a hook exists
Comment #53
vinyl_roads#42 seems to work but I had to replace :
$current_path = Url::fromRoute('<current>');
By
$current_path = \Drupal\Core\Url::fromRoute('<current>');
And I need to disable cache in Views otherwise the module didn’t update the attribute.
Comment #54
p4trizio CreditAttribution: p4trizio at Elicos commented#42 & #49 works fine for me as long as big_pipe is not enabled
Does anybody have the same problem as mine?
EDIT: The pager is in a Views block
Comment #55
Mikhail Stebenkov CreditAttribution: Mikhail Stebenkov commenteddel.
Comment #57
Joe Huggans#49 worked for me
Comment #58
Joe HuggansI have just found an error which occurs when using #49 - Undefined index: last, from this line in the code.
$total_pages = preg_replace('/^.*page=(\d+).*$/', '$1', $pager['items']['last']['href']);
This line gets the number of pages from looking at the value in the last href pager link, however $pager['items']['pages'] can be used to get this value instead, since $pager['items']['last' doesn't exist for me, so I have replaced this line with -
$total_pages = count($pager['items']['pages']) - 1;
Comment #59
LendudeCan we mark this 'closed (outdated)'? Happy to leave this open if people still find this relevant, but the odds of getting this into core have not gone up.
https://yoast.com/google-doesnt-use-rel-prev-next-for-pagination/
Comment #60
jordan8037310 CreditAttribution: jordan8037310 at Facet Interactive commentedWhile Google doesn't use rel prev/next for pagination, most other search engines do.
[1] reference: https://www.searchenginejournal.com/seo-friendly-pagination/275557/ - Reference the Tweet from a Bing search developer who claims they still use this markup.
Comment #62
Frank Pfabiganthis thread is important for seo aspects. read more about "seo-friendly pagination". altough google says that prev-/next isn't used anymore, google does not index all the paginated pages as you can see in google-searchconsole.
google treats a paginated page the same as a "normal" page.
so a paginated page also must have:
please give us the tools to unleash the power of paginated pages that are not in the index :-)
this involves views, drupal-core, breadcrumb, metatag module, token module and some other.
to ensure that everybody involved has the same knowledge-base, i suggest this lecture:
https://www.searchenginejournal.com/technical-seo/pagination/#close
Comment #64
Dubs CreditAttribution: Dubs as a volunteer and at Drupology commentedThanks @Jaesin for the code in #49. Here's a slightly different approach which uses the items and links already in the pager: -
Comment #65
prudloff CreditAttribution: prudloff at Insite commented#64 was not working for us because the view block was using a lazy builder.
We had to do something like this to make it work: https://www.drupal.org/project/drupal/issues/2769953#comment-12561253
Comment #66
prudloff CreditAttribution: prudloff at Insite commentedSince this looks like it could useful to other people, I create a contrib module for this: https://www.drupal.org/project/pager_metadata
Comment #73
LendudeSince there is a contrib module for this, and Google stopped using this years ago, I going to close this as outdated. If somebody has any new information that this is still something we should do in core, feel free to reopen this.
Thanks everybody that helped others that needed this over the years!