Djibouti crash out of AFCON 2025 Qualifiers after loss to Liberia

Djibouti crash out of AFCON 2025 Qualifiers after loss to Liberia

Action between Djibouti and Liberia © Courtesy

Read this story aloud

Listen to the clean text version of this article

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

Djibouti held Liberia to a goalless draw in the return tie but that wasn’t enough as they had lost the first leg encounter 2-0

Djibouti crashed out of the AFCON 2025 qualifiers following a 0-0 draw away to Liberia on Tuesday in the second leg of their Preliminary Round tie.
Liberia had won the first leg 2-0 when the two nations met in Morocco on Thursday 21 March in Marrakech. The match was played in Morocco because Djibouti does not have a stadium which meets CAF and FIFA standards for hosting of international football matches.
Djibouti has so far failed in all of its attempts to qualify for the African Cup of Nations since first trying to qualify for the AFCON 2000 edition.

More To Read

  • Djibouti records sharp increase in migrant transit as Gulf-bound journeys rise
  • Djibouti’s presidential election meets international standards – observers
  • Djibouti stops migrant boat with armed smugglers in Bab el-Mandeb crossing
  • Djibouti votes as President Ismail Guelleh seeks sixth term in office
  • Djibouti’s presidential candidates kick off campaign rallies ahead of election
  • Djibouti launches construction of Sh62.2 billion Salaam City, largest residential project in nation’s history

However, Djibouti can take positives from the results as it marked only the third time in their history that they have managed to get a result away from home in AFCON/World Cup qualifier matches after drawing 1-1 with Gambia in 2019 and 0-0 eSwatini in 2019 as well.
Djibouti still have hopes of redeeming themselves in the 2026 FIFA World Cup qualifiers where they are in Group A with Egypt, Burkina Faso, Guinea-Bissau, Sierra Leone, and Ethiopia. While they have already lost their first two matches (6-0 away to Egypt and 1-0 at home to Guinea-Bissau), desirable results against their other three opponents in the groups should do well for their pride.
Djibouti’s next matches will be in the 2026 FIFA World Cup qualifiers in June when they are set to play against Sierra Leone and Ethiopia.

Latest Stories

  • Ruto vows no room for ethnic politics as he fronts development milestones in fresh re-election strategy
  • Nigeria condemns killing of citizens in South Africa amid rising xenophobic violence
  • Kenya’s civic space downgraded to ‘repressed’ amid surge in rights violations – report
  • Controller of Budget calls for stricter controls on emergency spending after Sh144 billion used for debt repayment

Other Topics To Read

Top Stories Today

  • Ruto vows no room for ethnic politics as he fronts development milestones in fresh re-election strategy
  • Nigeria condemns killing of citizens in South Africa amid rising xenophobic violence
  • CoB calls for stricter controls on emergency spending after Sh144 billion used for debt repayment
  • Kenya’s civic space downgraded to ‘repressed’ amid surge in rights violations – report
  • Bellingham double fires 10-man England past Mexico into World Cup quarter-finals
  • KQ flight to New York forced to return to Nairobi after mid-air technical glitch

`;
}

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


Ruto vows no room for ethnic politics as he fronts development milestones in fresh re-election strategyPolitics
|Barack Oduor
|16 minutes ago

Nigeria condemns killing of citizens in South Africa amid rising xenophobic violenceAfrica
|Mwangi Maina
|29 minutes ago

Controller of Budget calls for stricter controls on emergency spending after Sh144 billion used for debt repaymentNews
|Lucy Mumbi
|1 hour ago

Stephen Yiembe makes history as first Kenyan referee appointed for UEFA Super CupFootball
|Erick Kariuki
|12 hours ago

Haaland’s heroics send Norway into historic first World Cup quarter-final as Brazil crash outSports
|Erick Kariuki
|3 hours ago

Taita Taveta County unveils cooperative fund to boost rural access to creditCoast
|Farhiya Hussein
|14 hours ago

2026 FIFA World Cup claims seven national team coachesInfographics
|Charity Pancras
|19 hours ago

DP Kindiki hails cooperatives as key to Kenya’s economic transformationNews
|Rachael Mutabasi
|1 day ago

Saba Saba organisers notify police of planned peaceful demonstration to ParliamentNews
|Rachael Mutabasi
|13 hours ago

Karua, Matiang’i demand arrest and resignation of PS Fikirini over Cecil Ouma shootingNews
|Rachael Mutabasi
|15 hours ago

Share.
Leave A Reply

Exit mobile version