Skip to content
All work

Case study

Nextward

A jobs and internships platform for students and professionals, in English and French. It brings together roles that companies post and listings imported every day from job boards, shows who can apply to each one, and writes a tailored CV and cover letter for any role.

Role
Sole designer and developer
Type
Independent product
Timeline
2021 – today
Status
Live
  • Laravel
  • Vue.js
  • Inertia.js
  • MySQL
  • Tailwind CSS
  • OpenAI & Claude APIs
Nextward’s home page on a laptop: “Find your next opportunity”, a search bar for roles and popular searches for internships, jobs and remote roles.

Problem

People looking for internships and jobs in IT search across Tunisian job boards, company career pages and international boards. Many listings don’t say whether someone in another country can apply, or whether the role pays, sponsors a visa or helps with relocation, and they come in French or English. Companies need a simple place to post roles and talk to applicants.

Ownership

I build Nextward on my own. It started in 2021 as Internly, the final-year project of my Bachelor’s in Computer Science at ISSAT Sousse: an internship platform where students applied and companies posted roles.

In 2026 I rebuilt it as Nextward on Laravel 13: jobs as well as internships, professionals as well as students, daily imports from job boards, every page in English and French, and AI tools for CVs and cover letters.

Constraints

  • I work on it alone, alongside contract work.
  • Imported listings come from sites I don’t control, in different formats and languages, and often leave out who can apply.
  • AI calls cost money, so the daily import can’t make one call per listing.
  • Its first users are in Tunisia: payments in dinars go through local gateways (Konnect and Flouci), and international cards through Lemon Squeezy.

Architecture

Laravel serves Vue pages through Inertia.js, with server-side rendering for public pages so search engines can read the listings. The data lives in MySQL. Imports, translations, emails and alert digests run as queued jobs on a scheduler.

Every morning the importer reads Tanitjobs and Keejob, and employer boards on Greenhouse, Lever and Ashby. It follows robots rules and request limits, keeps listings from the last 30 days, and shows a role listed on two boards only once. Each listing keeps its source and the time it was last checked.

Before a listing is added, an LLM (OpenAI or Claude, through Laravel’s AI package) reads it in a batch of ten. It sets the field, type, seniority, work mode, skills and who can apply, and sends scams and pay-to-apply posts to a review queue for an admin.

Every listing has an English and a French version. The AI translates without rewriting the employer’s text, and the original stays one click away.

Candidates keep up to 10 resumes. The AI can fill in a profile from an uploaded resume and write a CV and cover letter for one listing, using only facts from the candidate’s profile. CVs come in six themes, print to PDF through headless Chrome, download as Word files and are laid out right to left in Arabic.

Listing pages carry JobPosting structured data and are listed in a sitemap. Companies post roles, review applications and message candidates from their own workspace.

Tradeoff

Most imported listings don’t say whether someone in another country can apply. Guessing from the location or the company would put more roles under the Open worldwide filter, and send people to roles they can’t take.

Instead, each listing records who can apply: anyone, listed countries, people already allowed to work in that country, or unknown. Open worldwide only shows roles open to anyone, and a listing says when the source didn’t give pay, visa or relocation details. The cost is a shorter worldwide list: some open roles stay out of that filter until the source or an admin says more.

Testing & reliability

  • 306 PHPUnit tests in 51 files cover imports, applying, messaging, emails, credits, resumes, translations and the public pages. GitHub Actions builds the front end and runs them on every push.
  • If the AI key is missing, the account is out of credit or a call fails, the importer uses keyword rules instead and the run carries on.
  • A source pauses after three failed runs in a row, and rate-limited requests wait for the source’s Retry-After time.
  • Payments are checked again with the provider before credits are added, and a failed AI call gives its credit back.
  • Not done yet: there is no error monitoring beyond Laravel’s logs.

Outcome

Nextward is live at nextward.alabaganne.com. Anyone can browse and filter listings without an account, and candidates and companies can sign up. CV themes, Arabic CVs and paid credits are in the repository but not deployed yet.

Evidence

The screenshots below are public pages of the live site. Pages behind a login (the candidate dashboard, resumes, CV and letter kits, the company workspace and the imports admin) aren’t shown.

Screenshots

Finding roles

Anyone can search internships and jobs, in English or French, without an account.

Nextward home page screen (full-size image, opens in a new tab)

Home page

Search by role, company or skill, with popular searches underneath.

Nextward browse opportunities screen (full-size image, opens in a new tab)

Browse opportunities

Tabs for internships and jobs, one row of filters and an Open worldwide toggle.

Nextward in french screen (full-size image, opens in a new tab)

In French

Every public page and listing also has a French version.

Listings

Each listing says where it comes from, when it was last checked and who can apply.

Nextward listing page screen (full-size image, opens in a new tab)

Listing page

A listing translated from French by AI, with a link to apply on the source site.

Nextward who can apply screen (full-size image, opens in a new tab)

Who can apply

The original text in a fold-out, the countries that can apply, the source and its last check.

Joining

Candidates and companies sign up from the same form.

Nextward sign up screen (full-size image, opens in a new tab)

Sign up

Pick whether you’re looking for a role or hiring.

More case studies