Seatext library

How to Test SeaText Cross‑Origin Behavior Before Deploying to All SPA Domains

Add staging domains to SeaText's allowedOrigins list, deploy to a preview environment, and run automated Cypress or Playwright tests that verify the script loads, translates content, and shows no CORS errors. Then promote to...

Add staging domains to SeaText's allowedOrigins list, deploy to a preview environment, and run automated Cypress/Playwright tests that verify the script loads and translates without CORS errors. Then promote to production once all tests pass.

What is cross‑origin testing for SeaText?

Cross‑origin testing confirms that the SeaText script can be loaded and that its API calls succeed from each domain your SPA uses. Browsers enforce the Same‑Origin Policy, so a request from staging.example.com to seatext.com will be blocked unless SeaText returns the proper Access‑Control‑Allow‑Origin header.

Prerequisites

  • Access to the SeaText dashboard to edit allowedOrigins.
  • A preview or staging deployment that mirrors your production SPA.
  • Cypress or Playwright installed in your CI pipeline.
  • Knowledge of your SPA’s build commands (e.g., npm run build, ng serve).

Why cross‑origin testing matters before production

The Same‑Origin Policy protects users by preventing a page from reading data from a different origin without explicit permission. SeaText uses CORS headers to grant that permission. If the header is missing or mismatched, the browser blocks the request and you see errors such as:

Access to fetch at 'https://api.seatext.com/translate' from origin 'https://staging.example.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

These errors stop translation, break dynamic headline rewriting, and can cause a poor user experience. Testing before production ensures that every staging sub‑domain is correctly listed in allowedOrigins, that preflight OPTIONS requests succeed, and that your SPA does not encounter silent failures in the field.

Step 1: Configure allowedOrigins for staging

  1. Log in to the SeaText dashboard and open the domain settings page.
  2. Add each staging sub‑domain (e.g., staging.example.com, preview.example.com) to the allowedOrigins list.
  3. Save the changes. Propagation typically takes a few minutes.

Why this step matters: Without the origin in the whitelist, the browser will block the script’s fetch calls, resulting in the CORS error shown above. Adding the origin tells SeaText’s CDN to include the correct header in every response.

Step 2: Deploy to a preview environment

  1. Run the standard build command for your framework (e.g., npm run build for React, ng build for Angular, npm run build for Vue).
  2. Deploy the generated assets to your preview URL.
  3. Open the page in a browser and verify that the SeaText snippet (containing SEATEXTCODEINTEGRATION) appears in the <body> tag.

Why this step matters: The snippet is loaded asynchronously (as documented in the SeaText integration guide) which helps page‑load performance. If the snippet is missing or placed incorrectly, the script never runs and no translation occurs.

Step 3: Write automated tests

Both Cypress and Playwright can capture console errors, inspect network responses, and assert that translation occurs.

Cypress example

/// <reference types="cypress" />
const origins = [
  'https://staging.example.com',
  'https://preview.example.com'
];
origins.forEach(origin => {
  it(`checks SeaText on ${origin}`, () => {
    cy.visit(origin);
    // Capture console errors
    cy.on('window:before:load', win => {
      win.console.error = cy.stub().as('consoleError');
    });
    // Wait for the SeaText script to load
    cy.get('script[src*="seatext"]', { timeout: 10000 }).should('exist');
    // Assert no CORS errors
    cy.get('@consoleError').should('not.be.calledWithMatch', /CORS/);
    // Verify at least one element is translated
    cy.get('[data-seatext-translated]', { timeout: 5000 })
      .first()
      .should('contain.text', /./);
  });
});

Playwright example

import { test, expect } from '@playwright/test';
const origins = [
  'https://staging.example.com',
  'https://preview.example.com'
];
for (const origin of origins) {
  test(`SeaText works on ${origin}`, async ({ page }) => {
    const messages: string[] = [];
    page.on('console', msg => messages.push(msg.text()));
    await page.goto(origin);
    // Ensure script tag is present
    await expect(page.locator('script[src*="seatext"]')).toHaveCount(1);
    // Look for CORS errors in console output
    const corsErrors = messages.filter(m => /CORS/.test(m));
    expect(corsErrors).toHaveLength(0);
    // Check translation of a known element
    const translated = await page.locator('[data-seatext-translated]').first().innerText();
    expect(translated).not.toBe('');
  });
}

Why this step matters: Automated tests catch missing origins, mis‑typed domain names, and network‑level failures before any real user sees the problem.

Step 4: Run tests and verify no CORS errors

  1. Execute the test suite against the preview URLs (e.g., npm run test:ci).
  2. If any test fails, return to Step 1 and add the missing origin.
  3. When all tests pass, you have confidence that the script loads, the API calls succeed, and translation appears.

What to look for in DevTools: In the Console tab, CORS errors appear as red messages containing “blocked by CORS policy”. In the Network tab, a preflight OPTIONS request should return 200 with an Access-Control-Allow-Origin header matching your staging domain.

Step 5: Promote to production

  1. Merge the preview branch into the main branch.
  2. Run the production build (npm run build or ng build --prod).
  3. Deploy to the live domain.
  4. Run a quick smoke test (manual or automated) to confirm translation works on the live site.

Why this step matters: Production often uses a different domain (e.g., www.example.com). Add that domain to allowedOrigins before the final smoke test.

Step 6: Post‑deployment monitoring

  • Watch the SeaText dashboard for new origin warnings.
  • Schedule nightly CI runs that repeat the Cypress/Playwright suite against production.
  • Update allowedOrigins whenever you add a new sub‑domain, custom domain, or CDN edge.

Why ongoing monitoring matters: CORS headers are cached at CDN edges. A new edge node may need a few minutes to receive the updated whitelist. Continuous checks catch propagation delays.

Limitations and troubleshooting

  • Async loading: The SeaText snippet includes the async attribute. If you manually move the script or add defer, ensure the script still loads before your SPA renders translation‑dependent elements.
  • Local storage permissions: SeaText stores an identifier in localStorage. Browsers in private mode or with strict storage policies may block this. Verify that localStorage.setItem does not throw errors in the console.
  • Network inspection: In DevTools, filter by seatext.com. A successful request returns 200 and includes Access-Control-Allow-Origin: https://staging.example.com. A 403 or missing header indicates an origin mismatch.
  • Framework‑specific quirks:
    • React: Ensure the snippet is placed outside the root div#root so React’s virtual DOM does not overwrite it during hot reloads.
    • Vue: Add the snippet in public/index.html before the Vue app mounts.
    • Angular: Insert the snippet in src/index.html and verify that Angular’s ng serve does not strip the async attribute.
  • Build‑time vs runtime: The snippet runs at runtime. If you pre‑render pages (e.g., using Next.js static export), the script still executes in the browser, but you must ensure the generated HTML includes the snippet.

If you encounter a CORS error only in production, double‑check that the production domain is listed in allowedOrigins and that any edge proxy (Cloudflare, Fastly) is not removing the Access-Control-Allow-Origin header.

Key facts

FactDescription
Asynchronous loadingThe snippet includes the async attribute for the script tag, ensuring that the SeaText AI script loads asynchronously and does not block page rendering.
Local storage usageThe script stores an ID in localStorage. Your SPA must allow read/write access to local storage for the script to function correctly.
Cross‑origin considerationsSeaText requires each SPA domain to be listed in allowedOrigins to avoid Same‑Origin Policy blocks.
Build and serveBuild and serve your application using the standard commands for your framework (npm start, npm run serve, or ng serve).
Inspect the pageOpen browser Developer Tools (F12) and check the Console and Network tabs to verify that the SeaText script loads without errors.
Functionality checkEnsure that SeaText features, such as translation or dynamic headline rewriting, are working as expected within your SPA.

FAQ

  1. Why add staging domains to allowedOrigins? SeaText blocks requests from origins not on the whitelist to prevent unauthorized usage.
  2. Can I reuse the same test script for multiple domains? Yes. Parameterize the script with an array of URLs and loop through them.
  3. What does a CORS error look like in the console? It mentions “blocked by CORS policy” and shows the missing Access-Control-Allow-Origin header.
  4. What if I see a CORS error only in production? Verify that the production domain is in allowedOrigins and that no proxy strips the header.
  5. How often should I update allowedOrigins? Whenever you add a new sub‑domain, custom domain, or preview URL that will load SeaText.
  6. Do I need to disable the async attribute for testing? No. Async loading does not affect CORS behavior and should remain enabled for performance.
  7. How can I confirm that translation actually occurred? Look for elements with the attribute data-seatext-translated or check that visible text changes to the target language.
  8. What preflight request should I expect? An OPTIONS request to https://api.seatext.com that returns 200 with the correct Access-Control-Allow-Origin header.

Terminology

  • CORS – Cross‑Origin Resource Sharing, a browser mechanism that restricts cross‑origin HTTP requests unless the server sends appropriate headers.
  • allowedOrigins – SeaText setting that lists domains permitted to load the script and call its APIs.
  • preview environment – A staging deployment that mirrors production but is not exposed to end users.
  • preflight request – An OPTIONS request browsers send to verify CORS permissions before the actual request.
  • async attribute – An HTML attribute that tells the browser to download and execute the script without blocking page parsing.

Further reading

Further reading and comparison sources

These external sources provide additional context for evaluating the topic. Their inclusion is not an endorsement.

Learn more

Visit the website for more information.