Add a fully-featured careers section to your Larapen site. Post job openings, receive applications with resumes, and manage the entire hiring pipeline from the admin panel.
Job Positions
Create detailed job listings with descriptions, requirements, benefits, salary ranges, and employment types.
Application Pipeline
Receive applications with resumes, cover letters, and profile links. Track candidates through a 7-stage status workflow.
Category Organization
Organize positions by department or category using the unified Larapen category system.
Notification System
Automatic email notifications to admin users when new applications are submitted.
Use Cases
Company Careers Page
You run a company website on Larapen and need a professional careers section for hiring.
- Create job categories by department (Engineering, Marketing, Design, etc.).
- Post open positions with descriptions, requirements, benefits, and salary ranges.
- Set application deadlines or leave positions open until filled.
- Receive and review applications directly from the admin panel.
Agency with Multiple Clients
You manage multiple client sites and need to provide a job board feature on each.
- Install the add-on on each Larapen instance.
- Customize categories and position types per client.
- Enable CAPTCHA to prevent spam applications.
- Admin users receive email notifications for new applications.
Startup with Remote Team
You’re building a remote-first team and want to showcase your open positions.
- Mark positions as “Remote” for clear visibility on the front-end.
- Use experience level filters (Entry, Mid, Senior, Lead, Executive).
- Display salary ranges (optional, toggle per position).
- Applicants submit resumes (PDF/DOC/DOCX) and LinkedIn profiles alongside their applications.
Requirements
- Larapen CMS v1.0.0 or later
- PHP 8.3+
- MySQL 8.0+
Installation
Step 1: Upload the Add-on
In the admin panel, go to Admin → Extensions → Add-ons and click the Upload Add-on button. Select the add-on’s ZIP file: the system extracts it automatically and the add-on appears in the installed add-ons list.
Step 2: Activate the Add-on
Find Careers Portal in the list and click Activate. Its migrations, seeders (if any) and permissions are set up automatically.
Step 3: Configure
Navigate to Admin → Careers → Settings to configure job categories, application form fields, and recruiter notifications. See Configuration.
Purchase Code (License Key)
Careers Portal is sold as a separate product, so it has its own purchase code (license key), distinct from the purchase code of the main application and from the one of every other add-on. You are asked for it when you activate Careers Portal in Admin panel → Add-ons.
Our products are sold on three platforms. The way you receive a purchase code depends on where you bought the product.
| Platform / Marketplace | How you get the purchase code | Where to find it again |
|---|---|---|
| bedigit.com Store In-site purchase (Shop) |
Generated automatically when the order is paid, then sent by email, either in its own license email, or inside the order confirmation email. | My Account → My Licenses on bedigit.com |
| Gumroad | Created as soon as Gumroad notifies us of the sale, then sent in a separate email, in addition to the Gumroad receipt. | The license email, your Gumroad Library, and My Account → My Licenses on bedigit.com |
| Envato Market CodeCanyon |
Issued by Envato, not by us, and never sent by email: you download it yourself from your Envato account. | Envato account → Downloads → License certificate & purchase code |
1. bedigit.com Store (in-site purchase)
- As soon as the order’s payment status becomes Paid, a license key is generated automatically for every licensed item in the order (one key per purchased unit: buying 3 units gives 3 distinct keys).
- It is emailed to the address used on the order, either in a dedicated license email or inside the order confirmation email. Check your inbox and your spam / junk folder.
- The key stays available in your account under My Account → My Licenses. Keys are masked in the list; open the license detail page to reveal and copy the full key, see the domains it is activated on, and deactivate a domain to free an activation slot.
- The matching invoice is under My Account → My Orders.
2. Gumroad
- A Gumroad purchase produces two separate emails: the Gumroad receipt (sent by Gumroad, giving access to the files) and a license key email (sent by bedigit.com) that contains your purchase code.
- The license key email is generated as soon as Gumroad notifies us of the sale, so it normally arrives within seconds of the payment. Here too, check your inbox and your spam / junk folder.
- When the Gumroad product uses Gumroad’s own license-key feature, the same key also appears in your Gumroad receipt and under Library → your purchase on gumroad.com.
- Use the same email address on bedigit.com as on Gumroad: your keys are then linked to your account automatically and listed under My Account → My Licenses, even if you register after the purchase. You can also add a Gumroad key manually from My Account → My Gumroad Licenses.
3. Envato Market (CodeCanyon)
- Envato purchase codes are issued and delivered by Envato Market, never emailed by us, so there is nothing to look for in your spam folder: you retrieve the code from your Envato account.
- Log in to your Envato / CodeCanyon account, open the Downloads page, find the item, and choose License certificate & purchase code from the Download dropdown. The code is written in that certificate.
- An Envato purchase code looks like
12345678-90ab-cdef-1234-567890abcdef(8-4-4-4-12 characters). It never changes, and renewing item support does not issue a new one. - Official Envato article: Where Is My Purchase Code?
Configuration
The add-on ships with a config/careers.php file providing sensible defaults.
These can be overridden from the admin settings panel at Admin → Careers → Settings,
which stores values in the settings table (group careers).
| Setting | Description | Default |
|---|---|---|
careers_per_page |
Number of job positions displayed per page on the front-end listing. | 12 |
careers_allowed_resume_types |
Comma-separated list of allowed file extensions for resume uploads. | pdf,doc,docx |
careers_max_resume_size |
Maximum file size for resume uploads in kilobytes. | 5120 (5 MB) |
careers_notify_admin_on_application |
Send email notification to all admin users when a new application is received. | true |
careers_captcha_enabled |
Require CAPTCHA verification on the application submission form. | false |
Config File Defaults
Admin: Positions
The Positions page (Careers → Positions) manages your job listings.
Positions List
A paginated table (15 per page) showing all positions with:
- Title: translatable job title
- Category: linked career category
- Employment type (Full Time, Part Time, Contract, Freelance, Internship)
- Status (Draft / Published)
- Applications count: number of received applications
- Published date and deadline
Filterable by category and status.
Create & Edit
The position form contains translatable fields (per active locale) and non-translatable fields:
Translatable Fields
| Field | Type | Required |
|---|---|---|
title |
Text input | Yes (default locale) |
slug |
Text input (auto-generated from title) | No |
description |
WYSIWYG editor | Yes (default locale) |
requirements |
WYSIWYG editor | No |
benefits |
WYSIWYG editor | No |
meta_title |
Text input | No |
meta_description |
Textarea | No |
Non-Translatable Fields
| Field | Type | Notes |
|---|---|---|
category_id |
Select dropdown | Optional: career category from the unified categories table |
location |
Text input | e.g., “New York, NY” |
employment_type |
Select dropdown | Required: full_time, part_time, contract, freelance, internship |
experience_level |
Select dropdown | Required: entry, mid, senior, lead, executive |
department |
Text input | Free-text department name |
salary_min / salary_max |
Numeric inputs | Optional: salary range (max must be ≥ min) |
salary_currency |
Select dropdown | From active currencies table |
show_salary |
Checkbox | Toggle salary visibility on the front-end |
is_remote |
Checkbox | Mark as remote position |
status |
Select dropdown | Required: draft or published |
published_at |
Date picker | Defaults to current date |
closes_at |
Date picker | Optional: application deadline (must be in the future) |
position |
Number input | Sort order (auto-incremented) |
Admin: Applications
The Applications page (Careers → Applications) lists all received job applications.
Applications List
A paginated table showing:
- Applicant name (first + last name)
- Position applied for
- Status badge (color-coded)
- Applied on date
Filterable by position and status.
Application Detail
Click an application to view its full details:
- Contact information: name, email, phone
- Cover letter: full text
- Resume: download link (stored securely in
localdisk undercareers/resumes/) - LinkedIn profile: clickable URL
- Portfolio URL: clickable URL
- Internal notes: admin-only notes field
- IP address of submission
Status Workflow
Applications progress through a 7-stage pipeline. The admin can update the status and add internal notes at any stage.
| Status | Color | Description |
|---|---|---|
new |
Info (blue) | Freshly submitted, not yet reviewed |
reviewing |
Warning (yellow) | Under initial review |
shortlisted |
Primary (blue) | Candidate has been shortlisted |
interview |
Secondary (gray) | Interview scheduled or in progress |
offered |
Success (green) | Offer extended to the candidate |
hired |
Success (green) | Candidate has been hired |
rejected |
Danger (red) | Application rejected |
Resume Management
Uploaded resumes are stored on the local disk (not publicly accessible) under careers/resumes/.
Admins download resumes through an authenticated controller action that streams the file with the original filename.
- Allowed file types are configurable (default: PDF, DOC, DOCX).
- Maximum file size is configurable (default: 5 MB / 5120 KB).
- Resume files are automatically deleted when an application or its parent position is deleted.
Admin: Categories
Career categories (Careers → Categories) use the core Larapen unified categories table
with categorizable_type = 'career'.
Category Fields
| Field | Type | Notes |
|---|---|---|
name |
Translatable text | Required (default locale) |
slug |
Translatable text | Auto-generated from name |
description |
Translatable textarea | Optional |
is_active |
Checkbox | Toggle category visibility |
position |
Number | Sort order |
Admin: Settings
The settings page (Careers → Settings) is organized into three sections:
Display Options
- Positions Per Page: number of positions on the front-end listing (min: 4, max: 100).
Application Settings
- Allowed Resume Types: comma-separated list of accepted file extensions.
- Max Resume Size: maximum upload size in kilobytes (min: 512 KB, max: 50 MB).
- Admin Notifications: toggle email alerts for new applications.
CAPTCHA Protection
- Enable CAPTCHA for Applications: toggle CAPTCHA on the front-end application form.
- Requires a CAPTCHA provider to be configured in the core settings. A warning is shown if no provider is set up.
Front-end: Careers Listing
The careers listing page displays all open positions (published status, with a future or null deadline).
Page Features
- Category filter: sidebar or tab bar listing all active career categories with an “All Departments” option.
- Position cards: each card shows the job title, employment type, experience level, location, remote badge, salary range (if shown), and posting date.
- Pagination: controlled by the
careers_per_pagesetting. - SEO: page meta title and description are set via the
SeoService.
Category Filtering
Clicking a category navigates to /{locale}/careers/category/{slug}, which filters positions to that category.
The slug is resolved against the current locale with a fallback to the English translation.
Front-end: Position Detail
The position detail page (/{locale}/careers/{slug}) shows:
- Job title as the page heading
- Position metadata: employment type, experience level, location, remote badge, department
- Salary range (if
show_salaryis enabled for this position) - Posting date and deadline (or “Open until filled”)
- About the Role: full description (WYSIWYG content)
- Requirements section (if provided)
- What We Offer / Benefits section (if provided)
- Application form (see below)
- Related Positions: up to 3 other open positions from the same category
Front-end: Application Form
The application form is displayed on the position detail page and submits via POST
to /{locale}/careers/{slug}/apply.
Form Fields
| Field | Type | Validation |
|---|---|---|
first_name |
Text input | Required, max 255 characters |
last_name |
Text input | Required, max 255 characters |
email |
Email input | Required, valid email, max 255 characters |
phone |
Text input | Optional, max 50 characters |
cover_letter |
Textarea | Optional, max 10,000 characters |
resume |
File upload | Required, allowed types from settings, max size from settings |
linkedin_url |
URL input | Optional, valid URL, max 500 characters |
portfolio_url |
URL input | Optional, valid URL, max 500 characters |
On successful submission, the user is redirected back with a success message: “Thank you for your application! We'll review it and get back to you soon.”
Email Notifications
When careers_notify_admin_on_application is enabled, the add-on sends an email notification
to all admin users (is_admin = true) whenever a new application is submitted.
Notification Content
- Subject: “New Application for {Position Title}”
- Greeting: “New Job Application Received”
- Body: “{Applicant Name} has applied for the {Position Title} position.”
- Action button: Links to the admin applications list
- Footer: “Log in to your admin panel to review the application.”
The notification is sent via the mail channel using Laravel’s built-in MailMessage class.
CAPTCHA Integration
The application form supports CAPTCHA verification to prevent spam submissions.
How It Works
- Enable CAPTCHA in Careers → Settings.
- Ensure a CAPTCHA provider (e.g., reCAPTCHA, hCaptcha) is configured in Admin → Settings → General.
- The
SubmitApplicationRequestautomatically adds the CAPTCHA validation rule when enabled. - The CAPTCHA field name is resolved dynamically from the core
CaptchaService.
Multi-Language Support
The add-on ships with complete translations in English and French.
Translatable Content
- Positions: title, slug, description, requirements, benefits, meta_title, meta_description
- Categories: name, slug, description (via the core categories system)
Static UI Strings
All static text uses translation keys prefixed with careers::careers., organized into sections:
employment_types.*: Full Time, Part Time, Contract, Freelance, Internshipexperience_levels.*: Entry Level, Mid Level, Senior, Lead, Executiveapplication_statuses.*: New, Reviewing, Shortlisted, Interview, Offered, Hired, Rejectedadmin.*: all admin panel labels and messagesfront.*: all front-end labels and messagesnotifications.*: email notification strings
Updating
There are two ways to update this add-on: via the admin panel (recommended) or manually replacing files.
Method 1: Admin Panel Upload (Recommended)
- Download the latest
.zipfile of this add-on. - Go to Admin panel → Add-ons and click the Upload button.
- Select or drag the
.zipfile into the upload area. - A confirmation prompt will show the current and new version numbers. Click Replace to proceed.
- Go to Admin panel → System Update (
/admin/update) to apply any pending database migrations.
Method 2: Manual File Replacement
Step 1: Replace Files
Replace the add-on directory with the new version.
Step 2: Run Migrations
php artisan migrate
Pending migrations run once, so the command is safe to repeat.
Step 3: Clear Caches
php artisan config:clear
php artisan route:clear
php artisan view:clear
Step 4: Verify
Visit Admin → Careers → Positions to confirm the add-on is working correctly.
Uninstallation
Switching an add-on off without losing anything is a deactivation: go to Admin panel → Add-ons, find Careers Portal and click Deactivate.
- Its routes, views, admin menu entries and permissions stop being registered, and its front-end pages stop answering.
- Its database tables and all the data they hold are kept, and its files stay under
extensions/addons/careers/. Nothing is deleted. - The purchase code recorded at activation is kept too, so activating the add-on again does not ask for it.
- Deactivation is refused while another active add-on depends on this one: deactivate that add-on first.
Click Activate on the same card to switch it back on. Pending migrations are re-run, assets are republished, and the add-on picks up exactly where it left off.
Removing
Removing is permanent and destroys the add-on's data. The Remove button only appears on a deactivated add-on, so removal is always two steps:
- Deactivate Careers Portal (see Uninstallation).
- Click Remove on its card and confirm the prompt.
The admin panel then, in one pass:
- runs the add-on's uninstall hook, if it ships one, while its code is still on disk;
- revokes the permissions declared in its
addon.json; - rolls back its migrations (this drops its database tables and every row they hold) and purges its entries from the
migrationstable, so a later reinstall migrates from scratch; - deletes its published assets:
public/addons/careers/,public/vendor/careers/andstorage/app/public/addons/careers/; - deletes the add-on directory
extensions/addons/careers/; - deletes its row in the
addonstable (the recorded purchase code goes with it) and clears the application cache.
Removal is refused, with an explanatory message and before anything is destroyed, when the add-on is still active, when another active add-on depends on it, or when the web server (PHP) user cannot delete extensions/addons/careers/. In that last case, give that user write permission on the directory and on its parent, then try again.
Deleting the folder over FTP or SSH is not equivalent: the add-on's tables, its entries in the migrations table and its addons row are all left behind, and its card stays in the list. Use Remove in the admin panel instead.
Troubleshooting
Positions not showing on the front-end
- Ensure the position status is Published (not Draft).
- Check that the Application Deadline (
closes_at) has not passed. Expired positions are excluded from the front-end listing. - Verify the theme has the
pages/careers/index.blade.phpandpages/careers/show.blade.phpview files.
Resume upload fails
- Check the allowed file types in Careers → Settings (default: pdf, doc, docx).
- Verify the file size does not exceed the configured
careers_max_resume_sizelimit. - Ensure your PHP
upload_max_filesizeandpost_max_sizedirectives inphp.iniare large enough. - Check that the
storage/app/careers/resumes/directory is writable.
Admin not receiving email notifications
- Ensure
careers_notify_admin_on_applicationis enabled in settings. - Verify your mail configuration (
MAIL_MAILER,MAIL_HOST, etc.) in.env. - Check that the admin user has
is_admin = truein the database. - Review
storage/logs/laravel.logfor mail delivery errors.
CAPTCHA not appearing on the application form
- Ensure CAPTCHA is enabled in Careers → Settings.
- A CAPTCHA provider must be configured in the core settings (Admin → Settings → General).
- The theme’s application form template must include the CAPTCHA component
(check
@ifblocks in the Blade template).
Category filtering returns 404
- Verify the category slug exists and matches the URL parameter.
- The slug is resolved against the current locale first, then falls back to English. If neither matches, a 404 is returned.
- Ensure the category is marked as active.
Application form not submitting
- Check that the position is still open (published and deadline not passed). Submitting to a closed position returns a 404.
- Ensure the CSRF token is included in the form (
@csrfdirective). - Review validation errors: the resume field is required and must match the allowed types and size.
Translatable fields not saving
- Ensure the form submits translatable fields as nested arrays
(e.g.,
title[en],title[fr]). - The default locale fields are required; other locales are optional.
- Check that the
spatie/laravel-translatablepackage is installed and configured.
Careers Portal v1.0.0: Part of the Larapen CMS platform.
© BeDigit. All rights reserved.