Weave 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

Laravel Google Search Console Laravel Package

jeffersongoncalves/laravel-google-search-console

A Laravel package for integrating Google Search Console into your applications, making it easy to pull search performance data, manage sites, and query analytics directly from your Laravel codebase.

View on GitHub
Deep Wiki
Context7

Getting Started

This is the initial release, so treat the assessment as a baseline.

  1. Install and publish config

    composer require <vendor>/<package>
    php artisan vendor:publish --tag=<package>-config
    
  2. Pick an auth path. Two options are typical for Search Console:

    • Service account (best for server-side/scheduled jobs): create a service account in Google Cloud, enable the Google Search Console API, download the JSON key, point the package config at it.
    • OAuth (needed if you want per-user delegated access).

    Critically, the service account email must be added as a user on the Search Console property (Settings → Users and permissions → Add user), not just granted IAM roles in Cloud. This is the single most common "why am I getting 403" cause.

  3. Verify the property string. Search Console has two property flavours:

    • URL-prefix: https://example.com/
    • Domain: sc-domain:example.com

    The string you pass to the package must match exactly what appears in the property selector, including trailing slash and scheme.

  4. First use case — a smoke test. Run the smallest possible query: last 7 days of search analytics grouped by query, limited to 10 rows. Confirm you get data back before wiring anything into a dashboard or database. If it returns empty, check the property string and the service-account permission before assuming the integration is broken — a brand-new or low-traffic property legitimately returns nothing.

Where to look first in the source: the config file (for auth and default property), the main client/service class, and any DTO/collection classes returned by the three feature areas. The three surfaces exposed in 1.0.0 are search analytics, URL inspection, and sitemaps — read those three method groups and you've read the whole package.

Implementation Patterns

Never call the API on page render. Search Console is a reporting API with quotas and multi-day data lag; live calls in a controller are the fastest way to a slow app and a quota incident. The canonical pattern is a scheduled ingest into your own table:

Schedule::command('gsc:sync')->dailyAt('05:00');
  → for each configured property
    → for each date in the missing window
      → fetch search analytics (dimensions: date, query, page, country)
      → upsert into search_analytics table

Because the API is dimension-aggregated rather than raw-log, upserting on (property, date, query, page, country, search_type) is idempotent and safe to re-run. That makes backfills and late-arriving data trivial.

Backfill in date slices, not one big range. Loop day-by-day or week-by-week. You get resumability (a failure only costs one slice), you stay under per-request row caps, and you avoid re-pulling 16 months every time a job dies halfway.

Re-pull a rolling window, not just yesterday. Data for the last 2–3 days keeps changing as Google finalises it. Sync today-5 → today every night so yesterday's numbers self-heal. Store a synced_at so you can prove freshness.

Use searchType deliberately. The same page/query pair has different numbers for web, image, video, news, and discover. Decide whether you store one row per type or filter to web only — but decide it before you write the schema, because retrofitting a type dimension into a unique index is painful.

URL Inspection as a diagnostic job, not a bulk crawl. The inspection endpoint is for "why isn't this page indexed" checks. Wrap it in a queued job triggered on demand or for pages that recently changed, cache the verdict with a TTL (a few hours to a day), and surface verdict, coverageState, lastCrawlTime, and googleCanonical vs userCanonical. The canonical mismatch field catches more real bugs than anything else in the response.

Sitemaps fit naturally into the deploy pipeline. Submit on release (or when a sitemap.xml changes) and list on a schedule to alert when lastDownloaded goes stale or errors/warnings climb. Delete is useful for cleaning up environments or retiring URLs. Treat submit as fire-and-forget in a queued job — never block a deploy on Google's response.

Multi-tenant shape. If you run many properties, drive everything from a config array or a sites table, and put the property identifier into every method call rather than relying on a global default. Wrap the loop in a per-property try/catch so one misconfigured property doesn't abort the sync for the other fifty.

Gotchas and Tips

  • Data lag and finalisation. The freshest 2–3 days are provisional. Any dashboard that shows "yesterday's clicks" as final will look wrong two days later. Label recent data as provisional.
  • 16-month retention. The API will not give you history older than ~16 months, and it is not recoverable. If historical trend matters, your ingest job is the only archive — start it on day one and never skip it.
  • Row limits and pagination. Search analytics returns a capped number of rows per request. High-cardinality dimensions (query + page + country together) will silently truncate. Page through with startRow, and sanity-check totals against a coarser query (dimension = date only) to detect truncation.
  • Quotas. Per-site and per-project limits apply, and URL Inspection has a much tighter daily cap than search analytics. Batch inspection jobs need throttling and backoff; a 429 should requeue with delay, not retry immediately.
  • Property type mismatch. https://example.com/ and sc-domain:example.com return different data sets and neither errors if you ask for something plausible-but-wrong — you just get nothing. Validate the property format early and log the property string on every call.
  • Permissions for sitemaps. Submitting and deleting sitemaps requires an owner-level (or full) permission on the property. A read-only service account will read fine and fail on submit — a confusing asymmetry worth knowing before you debug it.
  • Timezone and date semantics. Search Console dates are Pacific Time, not UTC and not your app timezone. A whereDate on a UTC timestamp column will be off by a day at the boundary. Store the GSC date string as a date column and compare like-for-like.
  • Empty results are not errors. A 200 with zero rows is the normal response for a new property, a filter that matches nothing, or a dimension combination with no traffic. Don't let "empty" raise an exception and page someone.
  • Filters are exact and case-sensitive-ish. Filtering by a page requires the full canonical URL, not a path fragment. For prefix matching, use the operator-based filters rather than LIKE, and remember filters apply before aggregation, so combining a query filter with a query dimension can behave unexpectedly.
  • Extension points. The service client is the natural place to swap in a retrying HTTP client or a mock for tests — fake at the HTTP layer (Laravel's Http::fake) rather than mocking package internals, so upgrades don't break your test suite.
  • Version 1.0.0 caveat. This is the first release; the API surface may still move. Wrap it behind a thin application-level repository/service (your own SearchConsoleRepository) so that any eventual signature change in the package touches one file rather than every controller and job.
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.
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums
rlacerda83/query-parser
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings