If your website runs on PHP and you’re not using WordPress, you can use GA Connector’s server-side tracking library to capture where your leads came from and send that information to your CRM.
It captures attribution data such as UTM parameters, Google Ads click IDs (gclid), landing pages, and referrers.
The library works with Laravel, Symfony, CodeIgniter, and regular PHP websites. It’s free and open source and can be installed with Composer.
Why use server-side tracking?
With regular browser-based tracking, some attribution data can be lost because of ad blockers and browser privacy features.
Server-side tracking helps reduce this by routing tracking requests through your own website before sending the data to GA Connector.
This gives you a few advantages:
- More complete attribution: Because requests go through your own domain, they’re less likely to be blocked by browser privacy features or ad blockers.
- Works without WordPress: You can use GA Connector on any supported PHP website.
- Works with your existing CRM: The attribution data is sent to your existing GA Connector integration and appears in the same reports.
- Keeps your API key private: Your GA Connector API key stays on your server and isn’t exposed in your website’s browser code.
How does it work?
The setup looks like this:
Visitor → Your website → GA Connector → Your CRM
When someone visits your website, your server handles the tracking request and forwards the information to GA Connector.
When that visitor submits a form, GA Connector can connect the lead with the attribution information collected during their visit.
The visitor’s browser doesn’t need to send tracking requests directly to a third-party tracking domain.
What does my developer need to do?
The library doesn’t start tracking automatically after installation. A developer needs to connect it to your website.
The library handles:
- Loading the GA Connector tracking code
- Forwarding tracking data through your domain
- Adding your GA Connector API key securely
- Checking that your account and domain are configured correctly
Your developer needs to:
- Add the tracking code to the pages you want to track
- Create a tracking route on your domain, such as
yoursite.com/gac - Connect the tracker to your cookie consent setup, if you use one
- Make sure the configuration works with your website’s caching setup
For most PHP websites, this is a relatively small implementation: usually a line in your main template and a new route.
Supported CRMs
Server-side tracking works with the CRMs supported by GA Connector, including:
- Salesforce
- Zoho CRM
- Pipedrive
- Close
You don’t need a separate CRM integration for server-side tracking.
The PHP library collects the attribution data differently, but the information still goes to your existing GA Connector account and CRM integration.
Your lead records can include information such as:
- UTM source
- UTM medium
- UTM campaign
- Google Ads click ID (gclid)
- Landing page
- Referrer
Install the PHP tracking library
The following section is intended for developers implementing the library.
Requirements
| Requirement | Details |
|---|---|
| PHP | PHP 7.4 or newer (tested on PHP 7.4 and 8.3) |
| Composer | Used to install the library |
| Additional software | None. The library uses cURL when available but can work without it |
| GA Connector | Your GA Connector API key |
| Domain | Your website must be added as an allowed domain in your GA Connector account |
1. Install the package
Run this command from your project folder:
|
1 |
composer require gaconnector/server-side-tracking |
If your application doesn’t already load Composer packages, add:
|
1 |
require __DIR__ . '/vendor/autoload.php'; |
Tip: Store your API key in an environment variable such as GAC_API_KEY instead of adding it directly to your code.
2. Connect the library to GA Connector
Add the following code to a file that runs on every request, such as your application’s bootstrap or configuration file:
|
1 2 3 4 5 6 7 8 9 10 11 |
<?php // bootstrap.php require __DIR__ . '/vendor/autoload.php'; use GaConnector\Tracking\GaConnector; GaConnector::configure([ 'apiKey' => getenv('GAC_API_KEY'), 'baseUrl' => 'https://example.com/gac', ]); |
Replace example.com with your own domain.
3. Add tracking to your pages
Add the GA Connector tracking code to your main page template.
You can place it inside <head> or just before </body>:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<?php require __DIR__ . '/bootstrap.php'; ?> <!doctype html> <html> <head> <title>Contact us</title> <?= \GaConnector\Tracking\GaConnector::html() ?> </head> <body> <!-- your page and lead form --> </body> </html> |
Every page using this template will now include the tracker.
4. Create the tracking route
Create a small PHP file that handles GA Connector tracking requests:
|
1 2 3 4 5 6 |
<?php // gac.php require __DIR__ . '/bootstrap.php'; \GaConnector\Tracking\GaConnector::serve(); |
Then route requests under /gac/ to this file.
Apache
|
1 2 |
RewriteEngine On RewriteRule ^gac/ gac.php [L,QSA] |
nginx
|
1 2 3 |
location /gac/ { try_files $uri /gac.php?$query_string; } |
Your website will now handle these tracking endpoints:
| Address | Purpose |
|---|---|
GET /gac/js |
Loads the GA Connector tracker through your domain |
POST /gac/events/pageview |
Records a page view |
POST /gac/events/identify |
Connects a form submission to the visitor’s lead source using a hashed email |
5. Check that everything is working
Check your account connection
You can verify that your API key and domain are configured correctly from an admin or setup page.
Do not add this code to a public page.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
use GaConnector\Tracking\GaConnector; use GaConnector\Tracking\Exception\AccountVerificationException; use GaConnector\Tracking\Exception\NoHttpTransportException; try { $account = GaConnector::verifyAccount('example.com'); echo $account->allows('example.com') ? 'Connected' : 'Domain not added to this account'; } catch (AccountVerificationException $e) { // 401 = wrong API key // 403 = subscription inactive // 404 = account not found echo 'Connection failed: ' . $e->getStatus(); } catch (NoHttpTransportException $e) { echo 'Your server cannot make outgoing requests'; } |
Check a live page
- Open a page where tracking is installed.
- Open your browser’s Developer Tools (
F12). - Open the Console.
- Enter:
|
1 |
window.__gacStatus |
If the result is ok, tracking is working.
Advanced setup
The setup above should be enough for most websites. The following options are available for websites that need additional configuration.
Laravel, Symfony, and other PHP frameworks
The library works with PHP frameworks such as Laravel and Symfony.
Add the tracking code to your framework’s main layout and create a route for /gac/*.
If your framework already provides the incoming request, you can call the handlers directly:
|
1 2 3 4 |
use GaConnector\Tracking\Http\Request; $response = $gac->proxy()->handlePageview(Request::fromGlobals()); $response->emit(); |
The same approach can be used for the tracker script and identify handlers.
Cookie consent and Google Tag Manager
If your website uses a cookie consent banner, you can control when GA Connector starts tracking.
| Mode | What happens | Recommended for |
|---|---|---|
auto |
Tracking loads when the page opens | Websites without a consent banner |
consent |
Tracking waits until you load it | Websites using a cookie banner or Google Tag Manager |
When using consent mode, load the tracker after the visitor gives consent:
|
1 |
$gac->scriptTag(); |
The library doesn’t detect consent automatically, so your developer will need to connect this to your existing consent banner or Google Tag Manager setup.
Capture UTM parameters and gclid server-side
You can enable server-side context with:
|
1 |
'inlineContext' => true |
This allows the server to record information such as:
- Landing page URL
- Referrer
- Browser information
This can help preserve attribution information such as UTM parameters and Google Ads click IDs.
Important note about caching
Only enable inlineContext on pages that aren’t stored in a full-page cache.
If the page is cached, visitor-specific information could be included in the cached page.
For websites using full-page caching, keep inlineContext disabled and load visitor-specific information separately:
|
1 2 3 |
echo $gac->settingsScript(); // safe to cache echo $gac->contextScript(); // must not be cached echo $gac->scriptTag(); // tracker |
Cross-domain tracking
If visitors move between multiple domains you own, add those domains to internalDomains.
For example, a visitor might move from your main website to a separate booking website.
Adding both domains allows GA Connector to keep the visitor’s original lead source as they move between them.
Forms inside iframes
Forms inside iframes work without additional setup.
The tracker detects when it’s running inside an iframe and avoids recording the visit twice.
Configuration options
| Setting | Required | Default | Description |
|---|---|---|---|
apiKey |
Yes | None | Your GA Connector API key |
baseUrl |
Yes | None | Tracking URL on your domain, such as https://example.com/gac |
mode |
No | auto |
Use auto to load immediately or consent to wait for consent |
inlineContext |
No | false |
Records landing page, referrer, and browser information on the server. Use only on uncached pages |
internalDomains |
No | None | Other domains you own that should share attribution information |
iframeEnabled |
No | true |
Shares visitor information between a page and forms inside iframes |
debug |
No | false |
Displays additional information for troubleshooting |
Troubleshooting
If tracking isn’t working as expected, open a tracked page and enter the following in your browser console:
|
1 |
window.__gacStatus |
| Status | Meaning |
|---|---|
ok |
Tracking is working and the visit was recorded |
internal |
Tracking is working; the visitor came from another page on your website |
iframe |
Tracking is running inside an iframe and avoided recording a duplicate visit |
awaiting_consent |
Tracking is waiting for the visitor to give consent |
script_pending |
The tracker hasn’t loaded. Check whether yoursite.com/gac/js opens correctly |
conflict |
An older GA Connector tracking code is also installed on the page. Remove the old tracking code |
If you’re still having trouble, contact GA Connector support and include the status shown in the console.
Frequently asked questions
How do I track UTM parameters on a PHP website?
Install the GA Connector PHP library with Composer, add the tracking code to your main page template, and create a /gac/ route on your website.
GA Connector can then capture UTM source, medium, and campaign information and connect it to leads in your CRM.
Can I use GA Connector without WordPress?
Yes. If your website runs on PHP, you can use the server-side tracking library instead of the WordPress plugin.
It works with the same GA Connector account, CRM integrations, and reports.
Does server-side tracking work with ad blockers?
Because tracking requests go through your own domain instead of directly to a known third-party tracking domain, they’re less likely to be blocked.
However, no tracking method can guarantee that every visit will be captured.
Does it work with Laravel and Symfony?
Yes. The library works with PHP 7.4+ websites, including Laravel, Symfony, CodeIgniter, and custom PHP applications.
Does it work without JavaScript?
A small tracking script still runs in the visitor’s browser, but it loads through your own domain and sends the data through your server.
Server-side context can also capture information such as the landing page URL on the server.
Is my GA Connector API key exposed?
No. Your server adds the API key when it forwards tracking data to GA Connector, so the key isn’t included in your public website code.
Does it support cookie consent?
Yes, but you need to connect it to your existing consent setup.
Use consent mode and load the tracker after the visitor accepts tracking through your cookie banner or Google Tag Manager.
How much does it cost?
The PHP library is free and open source under the MIT licence.
You still need an active GA Connector subscription to send attribution data to your CRM.

