Fruitful Docs
GuidesCapture

Capture a page behind a login

Declare a login so a route captures with the user's signed-in browser session.

Routes that need a signed-in session name a login. Fruitful checks the session before capture and asks the user to sign in when it is missing. The package never sees credentials or cookies.

Declare the login

Logins live in capture.logins[] and are referenced by id from routes:

"logins": [
  {
    "id": "linkedin",
    "name": "LinkedIn",
    "reason": "LinkedIn captures need a logged-in browser session.",
    "checkUrl": "https://www.linkedin.com/in/me/",
    "signInUrl": "https://www.linkedin.com/login",
    "signedIn": {
      "selectors": ["[data-testid=\"mainFeed\"]", "section[data-view-name=\"profile-card\"]"]
    },
    "signedOut": {
      "reason": "LinkedIn redirected to a sign-in or checkpoint page.",
      "urls": [{ "pattern": { "hostname": "*.linkedin.com", "pathname": "/login*" } }],
      "html": ["id=\"rememberme-div\""]
    }
  }
]
  • checkUrl is loaded to test the session; signInUrl is opened for the user when it fails.
  • signedIn is the positive match: any listed condition matching the check page means the session is ready.
  • signedOut is the negative match against the final URL or HTML. Give it a reason; the user sees it.

A matcher can test urls (URL patterns), selectors (CSS), or html (literal substrings). List several: sites change their sign-in flow more often than their feed markup.

Attach it to the route

{ "id": "newsfeed", "kind": "collection", "login": "linkedin", "runsOn": ["desktop"], "binding": "newsfeed" }

A route with a login can only run where a signed-in browser exists, so runsOn is ["desktop"]. The registry rejects a reader or media route that needs a login and lists cloud.

What happens at capture time

  1. The Desktop app loads checkUrl in the user's own browser profile.
  2. If signedOut matches, or signedIn does not, capture stops with LoginRequired and the user is shown reason and signInUrl.
  3. Once the user signs in, capture resumes through the same route.

When authoring, the CLI capture behaves the same way: authoring capture returns LoginRequired and waits for you to sign in in the browser it opened. Never copy cookies or tokens into a package or a fixture; see Freeze private review evidence.

Reference: login, sessionMatcher.

On this page