Protectionism, taxes, fuel: The high cost of air travel in Africa
Protectionism, taxes, fuel: The high cost of air travel in Africa
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.
Restricted traffic rights granted by African governments to airlines limit the number of direct routes and the frequency of flights, and make journeys longer across the 54-nation continent
Travelling 1,000 kilometres (620 miles) by air between two capitals on the same continent does not seem like a challenge. But it can be one in Africa.
Take Libreville and Bangui for instance. The journey takes a minimum of nine hours, and requires passengers to change planes and shell out $1,000 — an example of the challenges facing Africa’s aviation sector because of high taxes and protectionist policies.
In comparison, a flight between Paris and Madrid — which crosses an equivalent distance — takes two hours and costs five times less.
More To Read
- Togo opens it’s gates to Africans in visa-free push for continental trade and integration
- How the Strait of Hormuz crisis is sending jet fuel prices soaring and shaking global aviation
- AfDB unveils aviation kitty to bridge Africa’s capital, infrastructure gaps
Unlike Europe, “travel on the continent is very difficult”, said Moses Munga, a 27-year-old construction consultant on his way to Ghana from Nairobi.
Like Munga, who told AFP that work took him to West Africa several times a year, civil engineer Ahmed Mekewi said he was a frequent business traveller.
But he confided: “I would have difficulty travelling on my own.”
Latest Stories
- Kenya reaffirms ties with Rwanda as it marks Liberation Day celebrations
- Morocco continue historic rise with record-breaking World Cup victory against Canada
- Serena Williams withdraws from Wimbledon doubles after knee injury, ending Venus reunion plans
- Report records 83 harassment incidents against Christians in Israel over three months
“The cost of travelling in Africa is very challenging,” the 29-year-old said.
Unlike Europe, which liberalised its aviation sector in the 1990s, Africa does not have “a unified… market”, an expert in the sector told AFP.
“In Europe, Air France for example can make as many flights as it wants, to Germany, Belgium, Spain or Portugal. This freedom… does not exist within Africa” for African carriers, he said, requesting anonymity because of the nature of his work.
Restricted traffic rights granted by African governments to airlines limit the number of direct routes and the frequency of flights, and make journeys longer across the 54-nation continent, he added.
According to a study conducted in 2021 by the International Air Transport Association (IATA) for the African Union, out of the 1,431 possible connections between each of the bloc’s member states, only 19 per cent had a weekly direct flight.
‘Protectionist mechanisms’
“Protectionist mechanisms favouring local airlines such as charging foreign companies more for flying over or operating inside their territory… hampers competition and drives prices up,” said Linden Birns, an aviation consultant based in South Africa.
As a result, “air traffic is so expensive in Africa (that) it isn’t really growing. Routes are very thinly served,” said Guy Leitch, aeronautical analyst and publisher of the South African magazine SA Flyer.
According to IATA, “Africa is the region where airfares are by far the highest”.
In addition to government restrictions, the price of intra-African air travel is also affected by “very high” taxes and the cost of aviation fuel, said Robert Lisinge, head of the energy, infrastructure and services section at the United Nations Economic Commission for Africa (UNECA).
Africa’s low refining capacity means that aviation fuel is largely imported and “often 30 per cent more expensive than elsewhere, including in… oil-producing countries,” said the expert source.
The Yamoussoukro Decision — a 1999 treaty intended to pave the way for the liberalisation of Africa’s aviation sector — was followed by the Single African Air Transport Market (SAATM) project in 2018 but such ambitions have struggled to take off.
“The whole idea is that if you liberalise the market, it will increase connectivity and it will reduce costs,” Lisinge told AFP.
But bilateral air service agreements between countries mean that many companies are unable to operate flights “as many times as they want, using the planes of whichever capacity they choose”, he added.
Economic gains
A 2014 IATA study covering 12 African nations said liberalisation would cause air traffic to jump 81 per cent between these countries.
Removing market barriers between just a dozen countries would generate $1.3 billion in additional economic activity and help create 155,000 jobs, the study concluded.
For now, “regional travel across the continent is very challenging and makes business hard”, said construction consultant Munga.
“Once you get a client and are drawing up your quotation, you must consider the costly cost of travel,” he said, adding that high airfares sometimes made a contract too expensive for certain customers, forcing him to abandon business opportunities.
For UNECA’s Lisinge, the continent stands to lose out on crucial economic gains unless air travel is made easier.
“Africa is a vast continent, connectivity by road is relatively poor,” he pointed out.
“Air transport is necessary to move the perishable goods, the traders, the expertise that will be required for intra-African trade”.
Other Topics To Read
Top Stories Today
- Weekly new Ebola cases reach highest level since outbreak began: WHO
- Kenya reaffirms ties with Rwanda as it marks Liberation Day celebrations
- Serena Williams withdraws from Wimbledon doubles after knee injury, ending Venus reunion plans
- Report records 83 harassment incidents against Christians in Israel over three months
- Clean mobility gains ground in trucks and buses, but fossil fuels still dominate at 94 per cent – report
- Over 1,000 Sudanese return home from Egypt under ongoing repatriation 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
Weight-loss drug Wegovy approved in UK for MASH-related liver fibrosisNews
|Charity Kilei
|13 hours ago
Eight arrested in Marsabit over Sh1.2 million SIM swap fraudNorthern Kenya
|Bashir Mbuthia
|12 hours ago
DP Kindiki hails cooperatives as key to Kenya’s economic transformationNews
|Rachael Mutabasi
|11 hours ago
Pope Leo XIV shines spotlight on Mediterranean migration crisisWorld
|Mary Wambui
|9 hours ago
SHA seeks Treasury funds to clear NHIF claims above Sh10 millionHealth
|Charity Kilei
|11 hours ago
Sudan’s people subject to ‘relentless’ drone strikes in El ObeidSudan
|UN News
|9 hours ago
Report records 83 harassment incidents against Christians in Israel over three monthsMiddle-East
|Bashir Mbuthia
|5 hours ago
Kenya reaffirms ties with Rwanda as it marks Liberation Day celebrationsRegional
|Bashir Mbuthia
|5 hours ago
Somalia intelligence agency kills Al-Shabaab mortar unit leader in Basra operationSomalia
|Bashir Mbuthia
|7 hours ago
CS Mbadi defends government’s Safaricom share sale as lawful and transparentNews
|Rachael Mutabasi
|15 hours ago
