Pagination splits long lists across numbered pages: a <ul class="pagination"> of .page-item elements wrapping .page-links, inside a labeled <nav>. Mark the current page with .active on the item and aria-current="page" on the link, resize with .pagination-lg or .pagination-sm, and align with flex utilities.
<link rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css">
<nav class="p-3" aria-label="Search results pages">
<ul class="pagination pagination-lg">
<li class="page-item disabled"><span class="page-link">« Previous</span></li>
<li class="page-item active"><a class="page-link" aria-current="page">1</a></li>
<li class="page-item"><a class="page-link" href="?page=2">Next »</a></li>
</ul>
<ul class="pagination pagination-sm justify-content-end mb-0">
<li class="page-item"><a class="page-link" href="?page=9" aria-label="Previous">«</a></li>
<li class="page-item active"><a class="page-link" aria-current="page">10</a></li>
</ul>
</nav>
The disabled "Previous" item is a <span> because .disabled only sets pointer-events: none, which does not stop keyboard users from tabbing to an <a>. Symbol-only links need an aria-label. Pagination is plain CSS; your server code or JavaScript generates the page numbers.