Как правильно сделать пагинацию?
Из приведенного кода не понятно как происходит
если я, например, нахожусь на проекте с id=5 (а id=6 еще нет) и при этом я нажимаю на кнопку "Вперед", то меня переносит на страницу с id=6, которой не существует и я просто получаю ошибку.

Общая идея пагинации: смотрите какие у вас есть данные в базе, исходя из этого формируете ссылки на возможные страницы.
Если вы хотите сделать цикличную - ну так и сделайте её, добавьте в свою логику проверку "id больше чем текущий не найдено" и корректно обрабатывайте.
Да простят меня боги чистого кода.

/**
 * Следующий пост
 *
 * @param $post_id
 *
 * @return string[]|null
 */
function next_post($post_id)
{
    global $link;
    $sql      = "SELECT * FROM projects WHERE id > " . $post_id . " ORDER BY id ASC LIMIT 1";
    $result   = mysqli_query($link, $sql);
    $nextpost = mysqli_fetch_assoc($result);

    if (!$nextpost) {
        return first_post();
    }

    return $nextpost;
}

/**
 * Предыдущий пост
 *
 * @param $post_id
 *
 * @return string[]|null
 */
function prev_post($post_id)
{
    global $link;
    $sql      = "SELECT * FROM projects WHERE id < " . $post_id . " ORDER BY id DESC LIMIT 1";
    $result   = mysqli_query($link, $sql);
    $prevpost = mysqli_fetch_assoc($result);

    if (!$prevpost) {
        return last_post();
    }

    return $prevpost;
}

/**
 * Первый пост
 *
 * @return string[]|null
 */
function first_post()
{
    global $link;
    $sql    = "SELECT * FROM projects WHERE ORDER BY id ASC LIMIT 1";
    $result = mysqli_query($link, $sql);
    $post   = mysqli_fetch_assoc($result);

    return $post;
}

/**
 * Последний пост
 *
 * @return string[]|null
 */
function last_post()
{
    global $link;
    $sql    = "SELECT * FROM projects WHERE ORDER BY id DESC LIMIT 1";
    $result = mysqli_query($link, $sql);
    $post   = mysqli_fetch_assoc($result);

    return $post;
}