Mombasa strengthens global cruise tourism appeal with landmark Asian cruise ship visit

Mombasa strengthens global cruise tourism appeal with landmark Asian cruise ship visit

MS Viking Yi Dun. (Photo: Farhiya Hussein)

Read this story aloud

Listen to the clean text version of this article

Ready
5 min listen
Audio reading is not supported on this browser.

KPA Managing Director Captain William Ruto said the arrival of the vessel marked an important development for Kenya’s cruise tourism industry, noting that most previous cruise arrivals had originated from Europe

The Port of Mombasa has witnessed a historic moment after MS Viking Yi Dun became the first cruise vessel from Asia to dock at the facility, arriving with 717 tourists and 450 crew members as Kenya continues to grow its position in the global cruise tourism market.
MS Viking Yi Dun, a Norway-flagged luxury cruise liner, arrived from Shanghai, China, as part of a long voyage across Africa, with planned stops in South Africa before completing its journey in Tarragona, Spain.
The nine-year-old vessel, measuring 228 metres in length and rising 10 decks above sea level, has a passenger capacity of about 930 people. Most of the tourists on board were from China, alongside visitors from 16 other nationalities.

More To Read

  • Shipping lines in Kenya given seven days to secure licences or face sanctions
  • Mombasa car dealers raise alarm over NTSA rules, cite delays in vehicle release
  • Senator Faki raises alarm over KPA outsourcing plans at Port of Mombasa
  • KIFWA leadership dispute lands in High Court as association appeals for calm
  • First LNG-powered cargo vessel docks at Mombasa Port
  • At least 1,700 passengers and crew confined on cruise ship in France after norovirus outbreak

The vessel’s arrival on Tuesday brought the number of cruise ships received at the port during the current October-to-June cruise season to nine, with a total of 4,889 tourists visiting the Kenyan coast.
This is an increase compared to the previous season, when five cruise ships brought 4,205 passengers to Mombasa.
The latest cruise season has seen growing interest from international travellers, with authorities projecting that Kenya could receive up to 20 cruise vessels by the end of 2026.

Latest Stories

  • LeBron James’ Lakers journey ends as NBA’s all-time scoring king moves on
  • Trump suffers major defeat as US Supreme Court protects birthright citizenship for migrants’ children
  • Nearly 50,000 missing after Venezuela twin earthquakes as death toll tops 1,700
  • Kenya unveils Sh1.081 trillion plan to transform agriculture and create 2 million jobs

A tourist receives a traditional coastal welcome at the Port of Mombasa. (Photo: Farhiya Hussein)
The tourists received a traditional coastal welcome at the Port of Mombasa, where Mijikenda cultural performers entertained them through music and dance before they left for excursions to explore various attractions in the country.
Captain Alex Sehlstedt said the voyage had been smooth and praised the weather conditions during the ship’s arrival in Mombasa.
“The weather has been beautiful so far, and the weather is perfect today. Not too warm for me as a polar bear,” said Captain Sehlstedt.
Kenya Ports Authority (KPA) Managing Director Captain William Ruto said the arrival of the vessel marked an important development for Kenya’s cruise tourism industry, noting that most previous cruise arrivals had originated from Europe.
“This is something that we have been looking for a long time. You are all aware that most of our cruise ships have been coming from Europe, but today this one is the first one coming from Asia,” said Captain Ruto.
He said the growth in cruise arrivals reflected increasing confidence in the Port of Mombasa as a gateway to East Africa and highlighted the role of the modern cruise terminal in attracting international operators.
He said, “The port had already welcomed its ninth cruise vessel in the current season. The steady increase in arrivals showed that the vision of establishing Mombasa as a leading cruise tourism hub was gradually being achieved.”
KPA Managing Director Captain William Ruto, right, nods to MS Viking Yi Dun’s arrival. (Photo: Farhiya Hussein)
Captain Ruto assured cruise visitors of their safety and said KPA would continue improving facilities and services to support the sector. He also urged cruise operators to consider extending their stopovers in Kenya to allow tourists more time to experience the country’s attractions.
“One day is not enough for visitors to experience the beautiful scenery of Mombasa and the many wonderful attractions our country has to offer,” he said.
Group Director of Operations at Pollman’s Tours and Safaris, Mohamed Hersi, said continued efforts to market Kenya internationally had contributed to the increase in cruise visitors arriving at the coast.
“I wish you were staying longer so that you can enjoy more of what Kenya has to offer,” said Hersi.
Wu Haijeng, a tourist from Beijing, said the cruise visit was a new experience for him despite having travelled to Kenya before.
“I want to see the beautiful views, animals, culture and history here. I want to have a good experience,” he said.
The arrival of MS Viking Yi Dun adds to efforts by tourism stakeholders to position Mombasa as a major cruise destination in East Africa while increasing the number of international visitors arriving through the port.

Other Topics To Read

Top Stories Today

  • Kenya eyes 2 million new jobs under Sh1.081 trillion agriculture plan
  • LeBron James leaves Los Angeles Lakers after eight seasons
  • US top court rejects Trump plan to end citizenship for children of illegal migrants
  • Death toll rises above 1,700 after Venezuela quakes, 50,000 still missing
  • State audit uncovers Sh6.2 billion payroll irregularities, triggers criminal investigation
  • UK to charge refugees over Sh1.7 million under new asylum programme

`;
}

return “;
}

function commentActionsMarkup(comment, canComment) {
const likeLabel = comment.liked_by_me ? ‘Liked’ : ‘Like’;
const likeCount = Number(comment.like_count || 0) > 0
? “
: ”;

const likeButton = canComment && comment.status === ‘approved’
? “
: “;

const replyButton = canComment && comment.status === ‘approved’
? “
: ”;

return `

`;
}

function commentMarkup(comment, canComment, isReply = false) {
const pendingBadge = comment.status && comment.status !== ‘approved’
? “
: ”;

const edited = comment.is_edited
? “
: ”;

const repliesHtml = Array.isArray(comment.replies) && comment.replies.length
? `

`
: “;

return `

`;
}

function replyFormMarkup(commentId) {
return `

`;
}

function setNotice(widget, message, type = ‘info’) {
const notice = widget.querySelector(‘[data-role=”notice”]’);
if (!notice) return;

if (!message) {
notice.hidden = true;
notice.textContent = ”;
notice.classList.remove(‘is-error’);
return;
}

notice.hidden = false;
notice.textContent = message;
notice.classList.toggle(‘is-error’, type === ‘error’);
}

function setCount(widget, total) {
const count = widget.querySelector(‘[data-role=”count”]’);
if (!count) return;

const num = Number(total || 0);
count.textContent = num === 1 ? ‘1 comment’ : `${num} comments`;
}

function openReplyBox(widget, commentId) {
widget.querySelectorAll(‘[data-role=”reply-box”]’).forEach(box => {
box.hidden = true;
box.innerHTML = ”;
});

const targetItem = widget.querySelector(`.ev-comments__item[data-comment-id=”${commentId}”]`);
if (!targetItem) return;

const replyBox = targetItem.querySelector(‘[data-role=”reply-box”]’);
if (!replyBox) return;

replyBox.hidden = false;
replyBox.innerHTML = replyFormMarkup(commentId);

const textarea = replyBox.querySelector(‘textarea’);
if (textarea) textarea.focus();
}

function closeReplyBox(container) {
if (!container) return;
container.hidden = true;
container.innerHTML = ”;
}

async function initCommentsWidget(widget) {
const state = {
articleId: Number(widget.dataset.articleId),
loadUrl: widget.dataset.loadUrl,
storeUrl: widget.dataset.storeUrl,
commentsBaseUrl: widget.dataset.commentsBaseUrl,
canComment: widget.dataset.canComment === ‘1’,
page: 1,
perPage: 10,
sort: ‘newest’,
total: 0,
hasMore: false,
busy: false
};

const list = widget.querySelector(‘[data-role=”list”]’);
const loading = widget.querySelector(‘[data-role=”loading”]’);
const empty = widget.querySelector(‘[data-role=”empty”]’);
const loadMoreBtn = widget.querySelector(‘[data-role=”load-more”]’);
const sortSelect = widget.querySelector(‘[data-role=”sort”]’);
const composerForm = widget.querySelector(‘[data-role=”composer-form”]’);

async function loadComments(reset = true) {
if (state.busy) return;

state.busy = true;
setNotice(widget, ”);
loading.hidden = false;

if (reset) {
state.page = 1;
list.innerHTML = ”;
empty.hidden = true;
}

try {
const url = new URL(state.loadUrl, window.location.origin);
url.searchParams.set(‘page’, state.page);
url.searchParams.set(‘per_page’, state.perPage);
url.searchParams.set(‘sort’, state.sort);

const response = await requestJson(url.toString(), {
method: ‘GET’,
headers: {
‘Accept’: ‘application/json’,
‘X-Requested-With’: ‘XMLHttpRequest’
}
});

const items = Array.isArray(response.data) ? response.data : [];
const meta = response.meta || {};

state.total = Number(meta.total || 0);
state.hasMore = !!meta.has_more;

setCount(widget, state.total);

if (reset) {
list.innerHTML = ”;
}

if (!items.length && reset) {
empty.hidden = false;
} else {
empty.hidden = true;
list.insertAdjacentHTML(
‘beforeend’,
items.map(item => commentMarkup(item, state.canComment, false)).join(”)
);
}

loadMoreBtn.hidden = !state.hasMore;
} catch (error) {
if (!list.children.length) {
empty.hidden = false;
empty.textContent = ‘Unable to load comments right now.’;
}
setNotice(widget, error.message || ‘Unable to load comments.’, ‘error’);
} finally {
loading.hidden = true;
state.busy = false;
}
}

async function submitTopLevelComment(form) {
const textarea = form.querySelector(‘textarea[name=”content”]’);
const button = form.querySelector(‘[data-role=”submit-comment”]’);

if (!textarea) return;

const content = textarea.value.trim();
if (!content) return;

const originalText = button ? button.textContent : ”;

try {
if (button) {
button.disabled = true;
button.textContent = ‘Posting…’;
}

const response = await requestJson(state.storeUrl, {
method: ‘POST’,
headers: buildJsonHeaders(),
body: JSON.stringify({
article_id: state.articleId,
content: content,
source_url: window.location.href
})
});

textarea.value = ”;

if (response?.data) {
list.insertAdjacentHTML(
‘afterbegin’,
commentMarkup(response.data, state.canComment, false)
);
empty.hidden = true;

if ((response.data.status || ”) === ‘approved’) {
state.total += 1;
setCount(widget, state.total);
}
}

setNotice(widget, response.message || ‘Comment posted successfully.’);
} catch (error) {
setNotice(widget, error.message || ‘Unable to post comment.’, ‘error’);
} finally {
if (button) {
button.disabled = false;
button.textContent = originalText || ‘Post comment’;
}
}
}

async function submitReply(form) {
const commentId = Number(form.dataset.commentId || 0);
const textarea = form.querySelector(‘textarea[name=”content”]’);
const button = form.querySelector(‘.ev-comments__reply-submit’);

if (!commentId || !textarea) return;

const content = textarea.value.trim();
if (!content) return;

const originalText = button ? button.textContent : ”;

try {
if (button) {
button.disabled = true;
button.textContent = ‘Posting…’;
}

const response = await requestJson(`${state.commentsBaseUrl}/${commentId}/reply`, {
method: ‘POST’,
headers: buildJsonHeaders(),
body: JSON.stringify({
article_id: state.articleId,
content: content,
source_url: window.location.href
})
});

if (response?.data) {
const parentItem = widget.querySelector(`.ev-comments__item[data-comment-id=”${commentId}”]`);
if (parentItem) {
const repliesWrap = parentItem.querySelector(‘.ev-comments__replies’);
if (repliesWrap) {
repliesWrap.insertAdjacentHTML(
‘beforeend’,
commentMarkup(response.data, state.canComment, true)
);
}
}
}

closeReplyBox(form.closest(‘[data-role=”reply-box”]’));
setNotice(widget, response.message || ‘Reply posted successfully.’);
} catch (error) {
setNotice(widget, error.message || ‘Unable to post reply.’, ‘error’);
} finally {
if (button) {
button.disabled = false;
button.textContent = originalText || ‘Post reply’;
}
}
}

async function toggleLike(button) {
const commentId = Number(button.dataset.commentId || 0);
if (!commentId) return;

const originalHtml = button.innerHTML;

try {
button.disabled = true;
button.innerHTML = ‘Working…’;

const response = await requestJson(`${state.commentsBaseUrl}/${commentId}/like`, {
method: ‘POST’,
headers: buildJsonHeaders(),
body: JSON.stringify({})
});

const liked = !!response?.data?.liked;
const likeCount = Number(response?.data?.like_count || 0);

button.classList.toggle(‘is-liked’, liked);
button.innerHTML = `${liked ? ‘Liked’ : ‘Like’} ${likeCount > 0 ? “ : ”}`;
} catch (error) {
button.innerHTML = originalHtml;
setNotice(widget, error.message || ‘Unable to update like.’, ‘error’);
} finally {
button.disabled = false;
}
}

if (composerForm) {
composerForm.addEventListener(‘submit’, function (e) {
e.preventDefault();
submitTopLevelComment(composerForm);
});
}

if (sortSelect) {
sortSelect.addEventListener(‘change’, function () {
state.sort = this.value || ‘newest’;
loadComments(true);
});
}

if (loadMoreBtn) {
loadMoreBtn.addEventListener(‘click’, function () {
if (state.busy || !state.hasMore) return;
state.page += 1;
loadComments(false);
});
}

widget.addEventListener(‘click’, function (e) {
const likeBtn = e.target.closest(‘[data-action=”toggle-like”]’);
if (likeBtn) {
e.preventDefault();
toggleLike(likeBtn);
return;
}

const replyBtn = e.target.closest(‘[data-action=”toggle-reply”]’);
if (replyBtn) {
e.preventDefault();
openReplyBox(widget, Number(replyBtn.dataset.commentId || 0));
return;
}

const cancelReplyBtn = e.target.closest(‘[data-action=”cancel-reply”]’);
if (cancelReplyBtn) {
e.preventDefault();
closeReplyBox(cancelReplyBtn.closest(‘[data-role=”reply-box”]’));
}
});

widget.addEventListener(‘submit’, function (e) {
const replyForm = e.target.closest(‘.ev-comments__reply-form’);
if (replyForm) {
e.preventDefault();
submitReply(replyForm);
}
});

loadComments(true);
}

document.addEventListener(‘DOMContentLoaded’, function () {
document.querySelectorAll(‘.ev-comments’).forEach(initCommentsWidget);
});
})();

Trending

Village elders to get Sh3,000 monthly stipend from July 1 under new planNews
|Mary Wambui
|13 hours ago
Court allows DPP to withdraw KCSE exam leakage case against former Merishaw principalNews
|Carolyne Kubwa
|12 hours ago
Refugees under new UK entry scheme to pay back for support granted, Minister saysNews
|Mary Wambui
|5 hours ago
EU eyes expanded cooperation with Ethiopian institutions following Borana visitEthiopia
|Abdirahman Khalif
|14 hours ago
Strait of Hormuz: UN evacuates 2,500 seafarers before attack freezes rescue operationMiddle-East
|UN News
|13 hours ago
UN warns Ebola outbreak in DRC could push one million more people into povertyDemocratic Republic of Congo
|Bashir Mbuthia
|11 hours ago
LeBron James’ Lakers journey ends as NBA’s all-time scoring king moves onSports
|Bashir Mbuthia
|4 hours ago

35 Al-Shabaab militants killed in joint Somalia-Türkiye airstrikes in Lower ShabelleSomalia
|Bashir Mbuthia
|10 hours ago

Gachagua alleges crackdown on media, says journalists at risk ahead of 2027 pollsNews
|Lucy Mumbi
|13 hours ago
Trump suffers major defeat as US Supreme Court protects birthright citizenship for migrants’ childrenWorld
|Bashir Mbuthia
|4 hours ago

Share.
Leave A Reply

Exit mobile version