Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Geoip Laravel Package

torann/geoip

GeoIP for Laravel resolves visitor location and currency from IP addresses via configurable services. Integrates with Laravel, supports multiple drivers/providers, and lets you publish config to choose and tune your lookup service.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require torann/geoip
    php artisan vendor:publish --provider="Torann\GeoIP\GeoIPServiceProvider" --tag="config"
    

    This publishes the config/geoip.php file, which is now required (breaking change in v3.0+).

  2. Configure a Provider: Edit config/geoip.php to enable a provider (e.g., ipdata.co):

    'providers' => [
        'ipdata' => [
            'enabled' => true,
            'api_key' => env('IPDATA_API_KEY'),
        ],
    ],
    

    Add your API key to .env (e.g., IPDATA_API_KEY=your_key_here).

  3. First Use Case: Resolve geolocation in a controller or middleware:

    use Torann\GeoIP\Facades\GeoIP;
    
    $location = GeoIP::getLocation();
    $country = $location->countryCode; // e.g., 'US'
    $city = $location->city;           // e.g., 'San Francisco'
    
  4. Middleware Integration (Optional but Common): Add GeoIPMiddleware to app/Http/Kernel.php to resolve geolocation for every request:

    protected $middleware = [
        \Torann\GeoIP\Middleware\GeoIPMiddleware::class,
    ];
    

    Access the location via request()->geoip anywhere in your app.


Implementation Patterns

Core Workflows

1. Request-Level Geolocation

Use GeoIPMiddleware to attach geolocation data to every request:

// app/Http/Middleware/GeoIPMiddleware.php (or Kernel.php)
public function handle($request, Closure $next) {
    $request->merge(['geoip' => GeoIP::getLocation()]);
    return $next($request);
}

Use Case: Geotargeted routing, compliance checks, or A/B testing. Access in controllers/views:

$country = $request->geoip->countryCode;

2. Caching for Performance

Cache results to reduce API calls (default: 1 hour):

// Cache for 24 hours
$location = GeoIP::getLocation(['cache_minutes' => 1440]);

Advanced: Use tagged caching for invalidation:

Cache::tags(['geoip'])->put('location:'.$ip, $data, 60);

3. Provider-Specific Features

Leverage provider capabilities (e.g., MaxMind’s ISP data or ipdata.co’s currency):

$location = GeoIP::getLocation(['provider' => 'maxmind']);
$currency = $location->currency; // Only available for ipdata.co

4. Event-Driven Extensions

Listen for geolocation events to trigger custom logic:

// EventServiceProvider.php
protected $listen = [
    'geoip.resolved' => [
        \App\Listeners\LogGeoIP::class,
        \App\Listeners\TriggerComplianceCheck::class,
    ],
];

Use Case: Analytics, compliance logging, or dynamic feature flags.

5. Dynamic Configuration

Override provider settings per request:

$location = GeoIP::getLocation([
    'provider' => 'ipfinder',
    'api_key' => 'dynamic_key_123',
]);

Integration Tips

With Laravel Features

  • Middleware: Combine with TrustProxies for cloud/CDN environments:
    $ip = $request->ip(); // Respects X-Forwarded-For
    $location = GeoIP::getLocationByIp($ip);
    
  • Policies: Restrict access by location:
    public function authorize() {
        return GeoIP::getLocation()->countryCode === 'US';
    }
    
  • Blade Views: Display location-aware content:
    @if(request()->geoip->countryCode === 'GB')
        <p>Welcome to the UK! Use GBP.</p>
    @endif
    

With Third-Party Services

  • Payment Gateways: Pass currency to Stripe:
    $currency = GeoIP::getLocation()->currency ?? 'USD';
    Stripe::setApiKey(env('STRIPE_KEY'));
    
  • Analytics: Send geodata to Mixpanel/Amplitude:
    $tracker->track('Page View', [
        'country' => $location->countryCode,
        'city' => $location->city,
    ]);
    

Testing

  • Mock geolocation in tests:
    GeoIP::shouldReceive('getLocation')
         ->once()
         ->andReturn((object) ['countryCode' => 'DE']);
    
  • Use GeoIP::fake() for isolated testing:
    GeoIP::fake(['countryCode' => 'FR']);
    

Gotchas and Tips

Pitfalls

  1. Missing Config File:

    • Error: Class 'Torann\GeoIP\GeoIP' not found or Call to undefined method.
    • Fix: Run php artisan vendor:publish --provider="Torann\GeoIP\GeoIPServiceProvider" --tag="config" after installing.
    • Prevention: Add to composer.post-autoload-dump in composer.json:
      "scripts": {
          "post-autoload-dump": [
              "php artisan vendor:publish --tag=geoip-config --ansi"
          ]
      }
      
  2. Provider API Limits:

    • Free tiers (e.g., ipdata.co) have request limits (e.g., 1,000/month).
    • Fix: Cache aggressively or upgrade to a paid plan.
    • Tip: Monitor usage via provider dashboards or log API calls:
      GeoIP::extend('ipdata', function ($app) {
          $client = new \GuzzleHttp\Client();
          $client->getMiddleware()->push(
              new \App\Http\Middleware\LogApiCalls()
          );
          return new \Torann\GeoIP\Providers\Ipdata($client);
      });
      
  3. IPv6 Support:

    • Some providers (e.g., MaxMind) require IPv6-compatible databases.
    • Fix: Ensure your MaxMind database includes IPv6 ranges or use ipdata.co (IPv6-friendly).
  4. Middleware Order:

    • GeoIPMiddleware must run before logic that depends on request()->geoip.
    • Fix: Place it early in $middleware or $middlewareGroups['web'].
  5. Caching Edge Cases:

    • Issue: Stale cached data if IP changes (e.g., VPN users).
    • Fix: Use short cache TTLs (e.g., 5 minutes) or invalidate on demand:
      Cache::forget('geoip:location:'.$ip);
      
  6. Provider-Specific Quirks:

    • ipdata.co: Returns country_name (e.g., "United States") instead of countryCode (e.g., "US"). Fix: Normalize in a service:
      $countryCode = strtoupper(substr($location->country_name, 0, 2));
      
    • MaxMind: Requires local database files (not API-only). Download from MaxMind and configure:
      'maxmind' => [
          'database_path' => database_path('geoip/GeoLite2-Country.mmdb'),
      ]
      

Debugging Tips

  1. Enable Logging: Add to config/geoip.php:

    'log' => [
        'enabled' => true,
        'channel' => 'single',
    ],
    

    Check logs for provider errors (e.g., API failures, rate limits).

  2. Inspect Raw Responses: Extend a provider to log raw data:

    GeoIP::extend('ipdata', function ($app) {
        $provider = new \Torann\GeoIP\Providers\Ipdata($app['http.client']);
        $provider->setLogger(app('log')->channel('geoip'));
        return $provider;
    });
    
  3. Test with Known IPs: Use hardcoded IPs to debug:

    $location = GeoIP::getLocationByIp('8.8.8.8'); // Google DNS
    
  4. Validate Provider Responses: Ensure required fields exist (e.g., countryCode):

    $location = GeoIP::getLocation();
    if (empty($location->countryCode)) {
        throw new \RuntimeException('Invalid geolocation data');
    }
    

Extension Points

  1. Custom Providers: Create a new provider by implementing `Torann\GeoIP\
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle