https://github.com/forrtproject/flora-chromium
https://github.com/forrtproject/flora-chromium
Last synced: about 1 month ago
JSON representation
- Host: GitHub
- URL: https://github.com/forrtproject/flora-chromium
- Owner: forrtproject
- License: mit
- Created: 2026-03-03T15:38:15.000Z (4 months ago)
- Default Branch: main
- Last Pushed: 2026-05-05T17:42:07.000Z (about 2 months ago)
- Last Synced: 2026-05-05T19:32:52.308Z (about 2 months ago)
- Language: TypeScript
- Size: 694 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 5
-
Metadata Files:
- Readme: README.md
- License: license
Awesome Lists containing this project
README
# FLoRA — Replication Tracker
**FLoRA** (Framework for Open and Reproducible Research Assessment) is a browser extension for Chrome and Edge that automatically detects academic papers on the web and checks whether they have replication or reproduction data in the [FORRT Replication Database](https://forrt.org/replication-database/).
When you visit an article page (PubMed, journal websites, preprint servers, etc.) or search on Google Scholar, FLoRA scans for DOIs, looks them up against the FORRT database, and shows you at a glance whether that research has been replicated or reproduced.
## What it does
- **Article pages**: Displays a banner at the top of the page summarizing replication/reproduction data for all DOIs found on the page. Inline badges also appear next to individual DOI links. Handles SPAs by detecting URL changes and re-scanning automatically.
- **Google Scholar**: Adds DOI pills and replication badges to the right-hand side of each search result (alongside the PDF link area). When a result lacks a native `.gs_ggs` container, one is created to match Scholar's own layout.
- **DOI extraction**: Extracts DOIs from meta tags, JSON-LD, link hrefs, visible text, and HTML tables. Handles word-break characters (zero-width spaces, soft hyphens) and validates DOI suffixes to avoid partial matches from split HTML.
- **DOI augmentation**: When a page or Scholar result doesn't have a DOI in its HTML, FLoRA queries [Crossref](https://www.crossref.org/) and [OpenAlex](https://openalex.org/) to resolve the article title to a DOI via fuzzy matching (token-set-ratio > 88%).
- **DOI popover**: Each DOI pill has a hover popover showing the full DOI string with a copy-to-clipboard button.
- **Clicking badges/links**: Opens the [FORRT replication landing page](https://forrt.org/flora-replication-atlas/) for the relevant DOI(s).
## Installation (developer mode)
Since this extension is not yet on the Chrome Web Store, you'll need to load it manually.
### Quick install
1. **[Download flora-extension.zip](https://github.com/forrtproject/flora_chromium/releases)** (built automatically from the latest code)
2. **Unzip** it to a folder on your computer
3. Open `chrome://extensions` (or `edge://extensions`)
4. Enable **Developer mode** (toggle in the top-right corner)
5. Click **Load unpacked** and select the unzipped folder
6. **You're done!** Navigate to any academic article page or Google Scholar to see FLoRA in action.
### Building from source
If you want to develop or modify the extension:
1. Install [Node.js](https://nodejs.org/) (v18 or later)
2. Clone and build:
```bash
git clone https://github.com/forrtproject/flora-chromium.git
cd flora-chromium
npm install
npm run build
```
3. Load the project root folder as an unpacked extension (as above).
After making changes, run `npm run build` and click the **reload** icon on the FLoRA extension card in `chrome://extensions`.
## Development
### Project structure
```
flora-chromium/
manifest.json # Chrome MV3 manifest
esbuild.config.ts # Build configuration
src/
shared/ # Shared modules used by all entry points
types.ts # Zod schemas, branded types, state types
doi-normalise.ts # DOI string normalisation
doi-extractor.ts # Extract DOIs from page HTML (meta, JSON-LD, visible text, tables)
doi-augment.ts # Resolve titles to DOIs via Crossref + OpenAlex
flora-api.ts # FORRT replication API client
messages.ts # Message types for content ↔ background
cache.ts # Session cache (chrome.storage.session)
debounce.ts # Debounce utility
background/
service-worker.ts # MV3 service worker — handles FLORA_LOOKUP messages
content-general/
index.ts # Content script for article pages (SPA-aware)
injector.ts # Banner, inline badge, and DOI popover rendering (Shadow DOM)
styles.css # Banner/badge styles
content-scholar/
index.ts # Content script for Google Scholar
observer.ts # MutationObserver + DOI extraction/augmentation for Scholar results
badge.ts # Scholar replication badge rendering (Shadow DOM)
styles.css # Scholar badge styles
options/
index.html # Options page
tests/
setup.ts # Chrome API mocks
helpers.ts # Test utilities (doi(), mockResult())
unit/ # Unit tests for all modules
fixtures/ # HTML fixtures for extractor tests
dist/ # Built output (generated by npm run build)
```
### Automated Workflows
* Opened pull request are tested against the [test workflow](.github/workflows/test.yml)
* Pushing to `main` creates a new draft release from latest sources.
* Pushing a tag to `main` will create a new release
### Commands
| Command | Description |
| -------------------- | ------------------------------ |
| `npm run build` | Build the extension (one-time) |
| `npm run watch` | Build and watch for changes |
| `npm test` | Run all unit tests |
| `npm run test:watch` | Run tests in watch mode |
| `npm run typecheck` | TypeScript type checking |
### Tech stack
- **TypeScript** (strict mode)
- **esbuild** for bundling (fast, <50KB bundles)
- **Zod** for API response validation
- **Vitest** + jsdom + msw for testing
- **Shadow DOM** for UI isolation (styles don't leak into host pages)
- **Manifest V3** (Chrome + Edge)
### How it works
1. **Content scripts** run on every page. They extract DOIs from the page using meta tags, JSON-LD, link hrefs, visible text, and HTML tables. Word-break characters are stripped and partial DOI suffixes are filtered out.
2. If no DOIs are found directly, the extension tries to resolve the page/article title to a DOI using the **Crossref API** first, then **OpenAlex** as a fallback (fuzzy title matching with token-set-ratio > 88%).
3. Found DOIs are sent to the **background service worker** via `chrome.runtime.sendMessage`.
4. The service worker checks its **session cache**, deduplicates in-flight requests, and calls the **FORRT Replication API** for any uncached DOIs.
5. Results are sent back to the content script, which renders **banners** and **inline badges** using Shadow DOM.
6. On **Google Scholar**, DOI pills with copy-to-clipboard popovers and replication badges are injected into the right-side `.gs_ggs` container of each result row (created if absent).
7. The content-general script detects **SPA navigations** (URL changes) and re-scans the page automatically.
## Data sources & credits
- **Replication / reproduction data** — [FORRT Replication Database](https://forrt.org/replication-database/).
- **Title → DOI resolution** — [Crossref](https://www.crossref.org/) and [OpenAlex](https://openalex.org/).
- **Retractions** — [Retraction Watch](https://retractionwatch.com/) / The Center for Scientific Integrity, made openly available in partnership with [Crossref](https://gitlab.com/crossref/retraction-watch-data) under [CC-BY 4.0](https://creativecommons.org/licenses/by/4.0/).
## License
This project is part of the [FORRT](https://forrt.org/) initiative.