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 -dThis 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.localEdit .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.shThe 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:reportThe 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=SSBQuery 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