11

I'm using pagination like the following:

public function index()
    {
        $jobs = Job::paginate(5);
        return view('job.index', compact('jobs'));
    }

In the view:

{{ $jobs->links() }}

There is a problem of generating two typical pages: /job and /job?page=1 the two page has the same contents.

I want to do anything that removes the query string page from the first page of the pagination.

I have tried the following:

if ($jobs->onFirstPage()){
  $jobs->setPageName('');
} 

But this corrupt the pagination, i.e the links of pages does not load correctly and the query string value remains for all pages.

Xorifelse
  • 7,878
  • 1
  • 27
  • 38
SaidbakR
  • 13,303
  • 20
  • 101
  • 195

14 Answers14

9

The effective solution for this issue that I have found is to edit the pagination template.

First publish the pagination template from the vendors using the following command from the root of the project:

php artisan vendor:publish --tag=laravel-pagination

Now a file at resources/views/vendor/pagination/default.blade.php should be found and it could be edited like the following using str_replace() for the urls of each page and back navigation button:

<li><a href="{{str_replace('?page=1','',$paginator->previousPageUrl())}}" title="{{__('Previous')}}" rel="prev">{{$foxPrev}}</a></li>

and

 <li><a href="{{str_replace('?page=1','',$url)}}">{{ $page }}</a></li>

Update:

A bug was found with ?page=10 so instead of using str_replace we should using preg_replace like the following:

<li><a href="{{preg_replace('/\?page=[1]$/','',$url)}}">{{ $page }}</a></li>

Update 2:

In case of using any customized name for the page number parameter other than page, we could use the paginator getter for the $pageName property like the following in the pagination template:

<li><a href="{{preg_replace('/\?'.$paginator->getPageName().'=[1]$/','',$url)}}">{{ $page }}</a></li>

To know more about how to use more than one pagination on the same page or how to customize the page number parameter $pageName from view, checkout this answer

SaidbakR
  • 13,303
  • 20
  • 101
  • 195
  • Expression '/((\?|\&)page=[1]$)|(page=[1]($|\&))/' OR '/((\?|\&)'.$paginator->getPageName().'=[1]$)|('.$paginator->getPageName().'=[1]($|\&))/' will cover all the cases. For example: '...?page=1', '...?page=1&brand=2', '...?brand=2&page=1&filter=3', '...?brand=2&page=1'. And it will not react on 'page=10' in any position. – Max Basmanov Oct 15 '22 at 03:11
  • I don't understand how this question is upvoted when removing all parameters from link will give us URL to the same page with same parameters. Like if we are on the page ?page=2 it will give us same link on Page 1. – KorbenDallas Nov 09 '22 at 19:03