A modern, web-based amateur radio logging application built with Next.js and PostgreSQL. This is a clone of Wavelog with a modern tech stack.
- Modern Amateur Radio Logging: Clean, intuitive interface for logging QSOs
- Multi-Station Support: Manage multiple stations under one account
- Award Tracking: Built-in DXCC and WAS award progress tracking
- LoTW Integration: Automatic upload and download with Logbook of the World
- QSL Management: Track paper QSL cards with image uploads
- Advanced Search: Powerful filtering and search capabilities
- Cloudlog API Compatibility: Full compatibility with third-party logging software
- SmartSDR Integration: Direct QSO uploads from FlexRadio SmartSDR
- API Key Management: Secure authentication for third-party integrations
- Responsive Design: Works seamlessly on desktop and mobile devices
- Open Source: MIT licensed and community-driven
- Frontend: Next.js 15 with TypeScript
- Backend: Next.js API Routes
- Database: PostgreSQL with native SQL
- Authentication: JWT-based authentication
- Styling: Tailwind CSS
- Deployment: Vercel-ready
- Node.js 18+
- PostgreSQL 13+ database
- Docker and Docker Compose (recommended)
- Git
- Clone the repository:
git clone <repository-url>
cd nextlog
- Start the application with Docker:
docker-compose up -d
This will start:
- PostgreSQL database on port 5432
- Nextlog application on port 3000
- PgAdmin (optional) on port 8081
- Open http://localhost:3000 in your browser
- Clone the repository:
git clone <repository-url>
cd nextlog
- Install dependencies:
npm install
- Set up PostgreSQL database:
# Install and start PostgreSQL (method varies by OS)
# Create database and user
createuser -U postgres nextlog
createdb -U postgres -O nextlog nextlog
- Run the database installation script:
./install-database.sh
- Set up environment variables:
cp .env.example .env.local
Edit .env.local
with your settings:
DATABASE_URL=postgresql://nextlog:password@localhost:5432/nextlog
JWT_SECRET=your-jwt-secret-key-change-this-in-production
NEXT_PUBLIC_API_URL=http://localhost:3000
ENCRYPTION_SECRET=supersecretkeyforencryption
- Start the development server:
npm run dev
- Open http://localhost:3000 in your browser
Nextlog includes a comprehensive database installation script that sets up the complete schema and reference data.
- Creates all required tables (users, stations, contacts, dxcc_entities, states_provinces)
- Sets up indexes for optimal performance
- Installs database functions and triggers
- Loads DXCC entities data (340+ countries/entities)
- Loads states/provinces data for awards tracking
- Verifies installation completeness
# Make the script executable
chmod +x install-database.sh
# Run the installation
./install-database.sh
The script will:
- Create the database if it doesn't exist
- Install the complete schema
- Load reference data
- Verify the installation
The script uses these default settings:
- Database:
nextlog
- User:
nextlog
- Password:
password
- Host:
localhost
- Port:
5432
You can modify these values at the top of the install-database.sh
file if needed.
The script requires these data files to be present:
scripts/dxcc_entities.sql
- DXCC entities reference datascripts/states_provinces_import.sql
- States/provinces reference data
Both files are included in the repository.
Nextlog includes comprehensive end-to-end tests using Playwright to ensure application stability and feature reliability.
# Run all tests
npm test
# Run tests for specific browser
npm run test:chromium
# Run tests in headed mode (visible browser)
npm run test:headed
# Run tests in UI mode for debugging
npm run test:ui
# View test report
npm run test:report
The test suite covers:
- Authentication: Login and registration flows
- Navigation: Page routing and redirects
- Forms: Input validation and submission
- Responsive Design: Mobile and desktop layouts
- Error Handling: Database connection failures
- Core Features: Contact management, awards, ADIF import/export
- Build Quality: JavaScript errors, CSS loading, performance
- Security: Protected routes and authentication redirects
Tests run automatically on:
- Pull requests to main/develop branches
- Pushes to main/develop branches
The CI workflow requires all tests to pass before merging. See /.github/workflows/ci.yml
and /.github/branch-protection.md
for setup details.
See /tests/README.md
for detailed testing documentation.
- Register: Create a new account with your amateur radio callsign
- Login: Sign in to access your logbook
- Log Contacts: Add new contacts with frequency, mode, RST, and other details
- View Logbook: Browse your logged contacts on the dashboard
Nextlog provides full compatibility with Cloudlog's API, allowing you to use any third-party amateur radio software that supports Cloudlog integration.
- FlexRadio SmartSDR - Direct QSO uploads
- Ham Radio Deluxe - Logging and rig control integration
- N1MM Logger+ - Contest logging integration
- WSJT-X - Digital mode QSO uploads
- Any software supporting Cloudlog API format
- Create API Key: Go to Station Settings → API Key Management
- Configure Software: Use the generated API key in your logging software
- Authentication: API keys work with standard Cloudlog authentication methods
All API requests require authentication using one of these methods:
X-API-Key: your_api_key
(header)Authorization: Bearer your_api_key
(header)api_key=your_api_key
(query parameter)"key": "your_api_key"
(JSON body for POST/PUT)
API Information
GET /api/cloudlog
- API status and informationGET /index.php/api
- Cloudlog compatibility endpoint
QSO Management
GET /api/cloudlog/qso
- Retrieve QSOs with filteringPOST /api/cloudlog/qso
- Create new QSOPUT /api/cloudlog/qso
- Update existing QSODELETE /api/cloudlog/qso
- Delete QSOPOST /index.php/api/qso
- SmartSDR compatibility endpoint
Station Information
GET /api/cloudlog/station
- Get station informationGET /api/cloudlog/station?station_id=123
- Get specific station
Reference Data
GET /api/cloudlog/bands
- Get available bandsGET /api/cloudlog/modes
- Get available modesGET /api/dxcc
- Get DXCC entitiesGET /api/states
- Get states/provinces
Retrieve QSOs
GET /api/cloudlog/qso?limit=100&offset=0&callsign=W1AW&band=20M&mode=SSB
Query Parameters:
limit
- Number of QSOs to return (max 1000, default 100)offset
- Starting offset for paginationcallsign
- Filter by callsignband
- Filter by bandmode
- Filter by modedate_from
- Filter by start date (YYYY-MM-DD)date_to
- Filter by end date (YYYY-MM-DD)station_id
- Filter by station IDconfirmed
- Only confirmed QSOs (true/false)
Create QSO
POST /api/cloudlog/qso
Content-Type: application/json
X-API-Key: your_api_key
{
"callsign": "W1AW",
"band": "20M",
"mode": "SSB",
"rst_sent": "59",
"rst_rcvd": "59",
"qso_date": "2024-01-15",
"time_on": "14:30:00",
"freq": "14.205",
"gridsquare": "FN31pr",
"name": "John",
"country": "United States",
"state": "CT"
}
SmartSDR ADIF Format
POST /index.php/api/qso
Content-Type: application/json
{
"key": "your_api_key",
"station_profile_id": "1",
"type": "adif",
"string": "<CALL:4>W1AW<QSO_DATE:8>20240115<TIME_ON:6>143000<BAND:3>20M<MODE:3>SSB<RST_SENT:2>59<RST_RCVD:2>59<EOR>"
}
Success Response
{
"success": true,
"qsos": [...],
"pagination": {
"limit": 100,
"offset": 0,
"total": 1500,
"has_more": true
}
}
Error Response
{
"success": false,
"error": "Missing required field: callsign"
}
- Default: 1000 requests per hour per API key
- Headers included in responses:
X-RateLimit-Limit
- Maximum requests per hourX-RateLimit-Remaining
- Remaining requestsX-RateLimit-Reset
- Reset time (unix timestamp)
- Create API Key in Nextlog station settings
- Configure SmartSDR:
- Open SmartSDR Settings
- Go to Logbook section
- Set URL:
http://your-nextlog-url/index.php/api/qso
- Set API Key: Your generated API key
- Enable automatic QSO upload
Ham Radio Deluxe Setup
- Go to Logbook → Online Logbook Services
- Select "Cloudlog"
- URL:
http://your-nextlog-url/api/cloudlog
- API Key: Your generated API key
WSJT-X Setup
- File → Settings → Reporting
- Select "Cloudlog"
- URL:
http://your-nextlog-url/api/cloudlog/qso
- API Key: Your generated API key
POST /api/auth/register
- User registrationPOST /api/auth/login
- User loginPOST /api/auth/logout
- User logoutGET /api/contacts
- Get user's contactsPOST /api/contacts
- Create new contactGET /api/contacts/[id]
- Get specific contactPUT /api/contacts/[id]
- Update contactDELETE /api/contacts/[id]
- Delete contactGET /api/stations
- Get user's stationsPOST /api/stations
- Create new stationGET /api/stations/[id]
- Get specific stationPUT /api/stations/[id]
- Update stationDELETE /api/stations/[id]
- Delete station
- Email, password, name
- Amateur radio callsign
- Grid locator
- QRZ.com credentials
- Timestamps
- Station information (callsign, name, operator)
- Location data (QTH, address, grid, lat/lon)
- Zone information (CQ, ITU)
- Equipment details (power, rig, antenna)
- Integration settings (QRZ, LoTW)
- Default station management
- User and station references
- Core contact data (callsign, frequency, mode, band, datetime)
- RST sent/received
- Location data (QTH, grid, lat/lon, country, state)
- DXCC and zone information
- QSL status (paper, eQSL, LoTW)
- Additional ADIF fields
- Notes and timestamps
- ADIF entity codes
- Country/entity names and prefixes
- Zone information (CQ, ITU)
- Geographic coordinates
- Reference data for awards tracking
- State/province codes and names
- DXCC entity associations
- Zone information
- Reference data for awards tracking
- Fork the repository
- Create a feature branch
- Make your changes
- Submit a pull request
This project is open source and available under the MIT License.
- Inspired by Wavelog
- Built for the amateur radio community