В стандартном пагинаторе (%%LengthAwarePaginator%%) есть пара досадных косяков: 1. При выводе пагинатора на страницах >= 2 - ссылка на первую страницу идет в виде **example.com/?page=1** и это создает "зеркало" страницы для поисковика - тот же самый контент находится и на странице **example.com/**. 2. Если зайти на страницу **example.com/?page=999999**, то мы не увидим 404 страницу ошибки, а просто увидим пустую страницу с пагинатором. Я написал решение этих двух проблем и выкладываю его, чтобы вы покритиковали и сказали как можно было сделать проще и изящнее. {{cut}} Изначально хотел просто подменить view (%%resources/views/vendor/pagination/default.blade.php%%), но уткнулся в то, что в %%LengthAwarePaginator%% нет метода для получения предыдущей страницы, есть только метод для получения url предыдущей страницы (%%(php)$paginator->previousPageUrl()%%). Если пробовать разбирать через него, то это будет плохим способом, т.к. изначально пагинатор может выводиться на разных страницах, соответственно "хардкодить" там все пути - не кошерно. Потом ((https://laravel.ru/docs/v5/pagination#cmt-537 наткнулся на комментарий)) @FreeWebber и понял, что это можно сделать через наследования, придется только чуть-чуть поколдовать. Пронаследовал %%Illuminate\Pagination\LengthAwarePaginator%% и изменил ((https://github.com/laravel/framework/blob/5.4/src/Illuminate/Pagination/AbstractPaginator.php#L140-L159 метод %%url()%%)) - сделал, чтобы при визите на любую страницу с **?page=X**, где **X** > 1 - у первой страницы (page=1) не добавлялся GET-параметр **page=1**: %%(php) 1) { $parameters = [$this->pageName => $page]; } if (count($this->query) > 0) { $parameters = array_merge($this->query, $parameters); } $url = $this->path; $params_delimiter = (Str::contains($this->path, '?') ? '&' : '?'); $params_query = http_build_query($parameters, '', '&'); $fragment = $this->buildFragment(); if (!empty($params_query)) { $url .= $params_delimiter . $params_query; } if (!empty($fragment)) { $url .= $fragment; } return $url; } } %% Положил это добро соответственно в %%App\Utils\SEOFriendlyPaginator.php%%. Затем в своем Controller использовал этот %%SEOFriendlyPaginator%% и: 1. Сделал редирект с **example.com/?page=1** на **example.com/** 2. Сделал вывод 404 ошибки, если каким-то образом у нас хотят получить страницу, которой не существует (аля **example.com/?page=999999** или **example.com/?page=0**) %%(php) input('page'); $items = Article::filtered(); // здесь применяется мой собственный scope - filtered, это что-то вроде published, но с нужной мне сортировкой $total = $items->count(); if (!is_null($page)) { if ($page == 1) { return return redirect($request->getPathInfo(), 301); } if (($page > ceil($total / $per_page)) || ($page < 1)) { // предотвращаем отображение страниц, которые выходит за пределы текущих данных abort(404); } } else { $page = 1; } $items = $items->skip(($page - 1) * $per_page)->take($per_page)->get(); // берем только нужные элементы $items = new SEOFriendlyPaginator($items, $total, $per_page, $page, ['path' => $request->getPathInfo()]); return view('index', [ 'items' => $items ]); } } %% Вывод элементов и пагинатора во **view** не изменился: %%(blade) @foreach ($items as $item) {{-- вывод каждого элемента --}} @endforeach {{-- Вывод пагинатора --}} {{ $items->links() }} %% Всё. Как уже и писал выше - предложения, критика и советы - приветствуются! :-)