├── .babelrc ├── .gitignore ├── .prettierignore ├── .prettierrc ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.MD ├── LICENSE ├── assets └── demo.gif ├── eslint.config.js ├── manifest_chromium.json ├── manifest_firefox.json ├── package-lock.json ├── package.json ├── postcss.config.js ├── public └── icons │ ├── icon128.png │ ├── icon16.png │ ├── icon32.png │ └── icon48.png ├── readme.md ├── scripts └── zip.js ├── src ├── assets │ ├── css │ │ └── style.css │ └── scrapegraphai_logo.svg ├── components │ ├── CreditsInfo.jsx │ ├── ModelSelector.jsx │ ├── UrlSelector.jsx │ ├── common │ │ └── Header.jsx │ └── ui │ │ ├── Alert.jsx │ │ ├── Loading.jsx │ │ ├── TextArea.jsx │ │ └── TextField.jsx ├── hooks │ ├── useAlert.js │ └── useApiKey.js ├── index.html ├── index.js ├── views │ ├── Home.jsx │ └── Settings.jsx └── workers │ └── background.js ├── tailwind.config.js └── webpack.config.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/preset-env", "@babel/preset-react"] 3 | } 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | .pnpm-debug.log* 9 | 10 | # Diagnostic reports (https://nodejs.org/api/report.html) 11 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 12 | 13 | # Runtime data 14 | pids 15 | *.pid 16 | *.seed 17 | *.pid.lock 18 | 19 | # zip 20 | *.zip 21 | 22 | # Directory for instrumented libs generated by jscoverage/JSCover 23 | lib-cov 24 | 25 | # Coverage directory used by tools like istanbul 26 | coverage 27 | *.lcov 28 | 29 | # nyc test coverage 30 | .nyc_output 31 | 32 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 33 | .grunt 34 | 35 | # Bower dependency directory (https://bower.io/) 36 | bower_components 37 | 38 | # node-waf configuration 39 | .lock-wscript 40 | 41 | # Compiled binary addons (https://nodejs.org/api/addons.html) 42 | build/Release 43 | 44 | # Dependency directories 45 | node_modules/ 46 | jspm_packages/ 47 | 48 | # Snowpack dependency directory (https://snowpack.dev/) 49 | web_modules/ 50 | 51 | # TypeScript cache 52 | *.tsbuildinfo 53 | 54 | # Optional npm cache directory 55 | .npm 56 | 57 | # Optional eslint cache 58 | .eslintcache 59 | 60 | # Optional stylelint cache 61 | .stylelintcache 62 | 63 | # Microbundle cache 64 | .rpt2_cache/ 65 | .rts2_cache_cjs/ 66 | .rts2_cache_es/ 67 | .rts2_cache_umd/ 68 | 69 | # Optional REPL history 70 | .node_repl_history 71 | 72 | # Output of 'npm pack' 73 | *.tgz 74 | 75 | # Yarn Integrity file 76 | .yarn-integrity 77 | 78 | # dotenv environment variable files 79 | .env 80 | .env.development.local 81 | .env.test.local 82 | .env.production.local 83 | .env.local 84 | 85 | # parcel-bundler cache (https://parceljs.org/) 86 | .cache 87 | .parcel-cache 88 | 89 | # Next.js build output 90 | .next 91 | out 92 | 93 | # Nuxt.js build / generate output 94 | .nuxt 95 | dist 96 | 97 | # Gatsby files 98 | .cache/ 99 | # Comment in the public line in if your project uses Gatsby and not Next.js 100 | # https://nextjs.org/blog/next-9-1#public-directory-support 101 | # public 102 | 103 | # vuepress build output 104 | .vuepress/dist 105 | 106 | # vuepress v2.x temp and cache directory 107 | .temp 108 | .cache 109 | 110 | # Docusaurus cache and generated files 111 | .docusaurus 112 | 113 | # Serverless directories 114 | .serverless/ 115 | 116 | # FuseBox cache 117 | .fusebox/ 118 | 119 | # DynamoDB Local files 120 | .dynamodb/ 121 | 122 | # TernJS port file 123 | .tern-port 124 | 125 | # Stores VSCode versions used for testing VSCode extensions 126 | .vscode-test 127 | 128 | # yarn v2 129 | .yarn/cache 130 | .yarn/unplugged 131 | .yarn/build-state.yml 132 | .yarn/install-state.gz 133 | .pnp.* 134 | .DS_Store 135 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | build/ 3 | dist/ 4 | public/ 5 | *.log -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": true, 3 | "singleQuote": true, 4 | "jsxSingleQuote": false, 5 | "trailingComma": "es5", 6 | "bracketSpacing": true, 7 | "bracketSameLine": true, 8 | "arrowParens": "always", 9 | "printWidth": 110, 10 | "tabWidth": 2, 11 | "useTabs": false, 12 | "quoteProps": "preserve" 13 | } 14 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, religion, or sexual identity 10 | and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | - Demonstrating empathy and kindness toward other people 21 | - Being respectful of differing opinions, viewpoints, and experiences 22 | - Giving and gracefully accepting constructive feedback 23 | - Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | - Focusing on what is best not just for us as individuals, but for the 26 | overall community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | - The use of sexualized language or imagery, and sexual attention or 31 | advances of any kind 32 | - Trolling, insulting or derogatory comments, and personal or political attacks 33 | - Public or private harassment 34 | - Publishing others' private information, such as a physical or email 35 | address, without their explicit permission 36 | - Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail address, 56 | posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at 63 | mvincig11@gmail.com. 64 | All complaints will be reviewed and investigated promptly and fairly. 65 | 66 | All community leaders are obligated to respect the privacy and security of the 67 | reporter of any incident. 68 | 69 | ## Enforcement Guidelines 70 | 71 | Community leaders will follow these Community Impact Guidelines in determining 72 | the consequences for any action they deem in violation of this Code of Conduct: 73 | 74 | ### 1. Correction 75 | 76 | **Community Impact**: Use of inappropriate language or other behavior deemed 77 | unprofessional or unwelcome in the community. 78 | 79 | **Consequence**: A private, written warning from community leaders, providing 80 | clarity around the nature of the violation and an explanation of why the 81 | behavior was inappropriate. A public apology may be requested. 82 | 83 | ### 2. Warning 84 | 85 | **Community Impact**: A violation through a single incident or series 86 | of actions. 87 | 88 | **Consequence**: A warning with consequences for continued behavior. No 89 | interaction with the people involved, including unsolicited interaction with 90 | those enforcing the Code of Conduct, for a specified period of time. This 91 | includes avoiding interactions in community spaces as well as external channels 92 | like social media. Violating these terms may lead to a temporary or 93 | permanent ban. 94 | 95 | ### 3. Temporary Ban 96 | 97 | **Community Impact**: A serious violation of community standards, including 98 | sustained inappropriate behavior. 99 | 100 | **Consequence**: A temporary ban from any sort of interaction or public 101 | communication with the community for a specified period of time. No public or 102 | private interaction with the people involved, including unsolicited interaction 103 | with those enforcing the Code of Conduct, is allowed during this period. 104 | Violating these terms may lead to a permanent ban. 105 | 106 | ### 4. Permanent Ban 107 | 108 | **Community Impact**: Demonstrating a pattern of violation of community 109 | standards, including sustained inappropriate behavior, harassment of an 110 | individual, or aggression toward or disparagement of classes of individuals. 111 | 112 | **Consequence**: A permanent ban from any sort of public interaction within 113 | the community. 114 | 115 | ## Attribution 116 | 117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 118 | version 2.0, available at 119 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. 120 | 121 | Community Impact Guidelines were inspired by [Mozilla's code of conduct 122 | enforcement ladder](https://github.com/mozilla/diversity). 123 | 124 | [homepage]: https://www.contributor-covenant.org 125 | 126 | For answers to common questions about this code of conduct, see the FAQ at 127 | https://www.contributor-covenant.org/faq. Translations are available at 128 | https://www.contributor-covenant.org/translations. 129 | -------------------------------------------------------------------------------- /CONTRIBUTING.MD: -------------------------------------------------------------------------------- 1 | # Contributing to ScrapeGraphAI 2 | 3 | Thank you for your interest in contributing to **ScrapeGraphAI**! We welcome contributions from the community to help improve and grow the project. This document outlines the guidelines and steps for contributing. 4 | 5 | ## Table of Contents 6 | 7 | - [Getting Started](#getting-started) 8 | - [Contributing Guidelines](#contributing-guidelines) 9 | - [Code Style](#code-style) 10 | - [Submitting a Pull Request](#submitting-a-pull-request) 11 | - [Reporting Issues](#reporting-issues) 12 | - [License](#license) 13 | 14 | ## Getting Started 15 | 16 | To get started with contributing, follow these steps: 17 | 18 | 1. Fork the repository on GitHub **(FROM pre/beta branch)**. 19 | 2. Clone your forked repository to your local machine. 20 | 3. Install the necessary dependencies from requirements.txt or via pyproject.toml as you prefere :). 21 | 4. Make your changes or additions. 22 | 5. Test your changes thoroughly. 23 | 6. Commit your changes with descriptive commit messages. 24 | 7. Push your changes to your forked repository. 25 | 8. Submit a pull request to the pre/beta branch. 26 | 27 | N.B All the pull request to the main branch will be rejected! 28 | 29 | ## Contributing Guidelines 30 | 31 | Please adhere to the following guidelines when contributing to ScrapeGraphAI: 32 | 33 | - Follow the code style and formatting guidelines specified in the [Code Style](#code-style) section. 34 | - Make sure your changes are well-documented and include any necessary updates to the project's documentation and requirements if needed. 35 | - Write clear and concise commit messages that describe the purpose of your changes and the last commit before the pull request has to follow the following format: 36 | - `feat: Add new feature` 37 | - `fix: Correct issue with existing feature` 38 | - `docs: Update documentation` 39 | - `style: Improve formatting and style` 40 | - `refactor: Restructure code` 41 | - `test: Add or update tests` 42 | - `perf: Improve performance` 43 | - Be respectful and considerate towards other contributors and maintainers. 44 | 45 | ## Code Style 46 | 47 | Please make sure to format your code accordingly before submitting a pull request. 48 | 49 | ### Python 50 | 51 | - [Style Guide for Python Code](https://www.python.org/dev/peps/pep-0008/) 52 | - [Google Python Style Guide](https://google.github.io/styleguide/pyguide.html) 53 | - [The Hitchhiker's Guide to Python](https://docs.python-guide.org/writing/style/) 54 | - [Pylint style of code for the documentation](https://pylint.pycqa.org/en/1.6.0/tutorial.html) 55 | 56 | ## Submitting a Pull Request 57 | 58 | To submit your changes for review, please follow these steps: 59 | 60 | 1. Ensure that your changes are pushed to your forked repository. 61 | 2. Go to the main repository on GitHub and navigate to the "Pull Requests" tab. 62 | 3. Click on the "New Pull Request" button. 63 | 4. Select your forked repository and the branch containing your changes. 64 | 5. Provide a descriptive title and detailed description for your pull request. 65 | 6. Reviewers will provide feedback and discuss any necessary changes. 66 | 7. Once your pull request is approved, it will be merged into the pre/beta branch. 67 | 68 | ## Reporting Issues 69 | 70 | If you encounter any issues or have suggestions for improvements, please open an issue on the GitHub repository. Provide a clear and detailed description of the problem or suggestion, along with any relevant information or steps to reproduce the issue. 71 | 72 | ## License 73 | 74 | ScrapeGraphAI is licensed under the **MIT License**. See the [LICENSE](LICENSE) file for more information. 75 | By contributing to this project, you agree to license your contributions under the same license. 76 | 77 | ScrapeGraphAI uses code from the Langchain 78 | frameworks. You find their original licenses below. 79 | 80 | LANGCHAIN LICENSE 81 | https://github.com/langchain-ai/langchain/blob/master/LICENSE 82 | 83 | Can't wait to see your contributions! :smile: 84 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2024, ScrapeGraphAI Chrome Extension 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | 3. Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /assets/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ScrapeGraphAI/scrapegraphai-browser-extension/084ac867a2a7708a8f11a320b26315253a33604f/assets/demo.gif -------------------------------------------------------------------------------- /eslint.config.js: -------------------------------------------------------------------------------- 1 | import globals from 'globals'; 2 | import pluginJs from '@eslint/js'; 3 | import pluginReact from 'eslint-plugin-react'; 4 | import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended'; 5 | 6 | /** @type {import('eslint').Linter.Config[]} */ 7 | export default [ 8 | { files: ['**/*.{js,mjs,cjs,jsx}'] }, 9 | { 10 | languageOptions: { 11 | globals: { 12 | ...globals.browser, 13 | ...globals.webextensions, 14 | }, 15 | }, 16 | }, 17 | pluginJs.configs.recommended, 18 | pluginReact.configs.flat.recommended, 19 | eslintPluginPrettierRecommended, 20 | { ignores: ['node_modules/', 'dist/'] }, 21 | ]; 22 | -------------------------------------------------------------------------------- /manifest_chromium.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifest_version": 3, 3 | "name": "ScrapeGraphAI", 4 | "version": "0.1.1", 5 | "action": { 6 | "default_icon": { 7 | "16": "public/icons/icon16.png", 8 | "32": "public/icons/icon32.png", 9 | "48": "public/icons/icon48.png", 10 | "128": "public/icons/icon128.png" 11 | }, 12 | "default_popup": "index.html" 13 | }, 14 | "background": { 15 | "service_worker": "background.js", 16 | "type": "module" 17 | }, 18 | "permissions": ["tabs", "storage", "downloads", "notifications"], 19 | "host_permissions": ["https://api.scrapegraphai.com/v1/*"] 20 | } 21 | -------------------------------------------------------------------------------- /manifest_firefox.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifest_version": 3, 3 | "name": "ScrapeGraphAI", 4 | "version": "0.1.1", 5 | "action": { 6 | "default_icon": { 7 | "16": "public/icons/icon16.png", 8 | "32": "public/icons/icon32.png", 9 | "48": "public/icons/icon48.png", 10 | "128": "public/icons/icon128.png" 11 | }, 12 | "default_popup": "index.html" 13 | }, 14 | "background": { 15 | "scripts": ["background.js"] 16 | }, 17 | "permissions": ["tabs", "storage", "downloads", "notifications"], 18 | "host_permissions": ["https://api.scrapegraphai.com/v1/*"], 19 | "browser_specific_settings": { 20 | "gecko": { 21 | "id": "{a4848eb9-7b24-4585-b079-243f8c79d8e1}" 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "scrapegraphai-chrome", 3 | "version": "0.0.1", 4 | "main": "index.js", 5 | "type": "module", 6 | "scripts": { 7 | "build:firefox": "webpack --env firefox=true", 8 | "build:chromium": "webpack --env chromium=true", 9 | "format": "prettier --write .", 10 | "lint": "eslint .", 11 | "zip:firefox": "webpack --env firefox=true && node ./scripts/zip.js", 12 | "zip:chromium": "webpack --env chromium=true && node ./scripts/zip.js" 13 | }, 14 | "keywords": [], 15 | "author": "ScrapeGraphAI", 16 | "license": "BSD-3-Clause", 17 | "description": "", 18 | "dependencies": { 19 | "autoprefixer": "^10.4.20", 20 | "eslint-config-prettier": "^9.1.0", 21 | "eslint-plugin-prettier": "^5.2.1", 22 | "flowbite-react-icons": "^1.2.0", 23 | "postcss": "^8.4.41", 24 | "react": "^18.3.1", 25 | "react-dom": "^18.3.1", 26 | "react-router-dom": "^6.26.0", 27 | "scrapegraph-js": "^0.0.3", 28 | "tailwindcss": "^3.4.9" 29 | }, 30 | "devDependencies": { 31 | "@babel/core": "^7.25.2", 32 | "@babel/preset-env": "^7.25.3", 33 | "@babel/preset-react": "^7.24.7", 34 | "@eslint/js": "^9.16.0", 35 | "archiver": "^7.0.1", 36 | "babel-loader": "^9.1.3", 37 | "copy-webpack-plugin": "^12.0.2", 38 | "css-loader": "^7.1.2", 39 | "eslint": "^9.16.0", 40 | "eslint-plugin-react": "^7.37.2", 41 | "globals": "^15.12.0", 42 | "html-webpack-plugin": "^5.6.0", 43 | "postcss-loader": "^8.1.1", 44 | "prettier": "^3.4.1", 45 | "style-loader": "^4.0.0", 46 | "svg-url-loader": "^8.0.0", 47 | "terser-webpack-plugin": "^5.3.10", 48 | "webextension-polyfill": "^0.12.0", 49 | "webpack": "^5.93.0", 50 | "webpack-cli": "^5.1.4", 51 | "webpack-dev-server": "^5.0.4" 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | import autoprefixer from 'autoprefixer'; 2 | import tailwindcss from 'tailwindcss'; 3 | 4 | export default { 5 | plugins: [tailwindcss(), autoprefixer()], 6 | }; 7 | -------------------------------------------------------------------------------- /public/icons/icon128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ScrapeGraphAI/scrapegraphai-browser-extension/084ac867a2a7708a8f11a320b26315253a33604f/public/icons/icon128.png -------------------------------------------------------------------------------- /public/icons/icon16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ScrapeGraphAI/scrapegraphai-browser-extension/084ac867a2a7708a8f11a320b26315253a33604f/public/icons/icon16.png -------------------------------------------------------------------------------- /public/icons/icon32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ScrapeGraphAI/scrapegraphai-browser-extension/084ac867a2a7708a8f11a320b26315253a33604f/public/icons/icon32.png -------------------------------------------------------------------------------- /public/icons/icon48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ScrapeGraphAI/scrapegraphai-browser-extension/084ac867a2a7708a8f11a320b26315253a33604f/public/icons/icon48.png -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # 🕷️ ScrapeGraphAI Chrome extension 2 | 3 | The official extension for Chromium-based browsers, such as Chrome, Opera, Brave, and others, as well as Firefox. 4 | 5 |  6 | 7 | ## Installation 8 | 9 | You can install the extension using one of these methods: 10 | 11 | ### 1. Browser Extension Stores (Recommended) 12 | 13 | #### Chrome and Chromium-based browsers 14 | 1. Visit the [Chrome Web Store](https://chrome.google.com/webstore) (coming soon) 15 | 2. Search for "ScrapeGraphAI" 16 | 3. Click "Add to Chrome" 17 | 18 | #### Firefox 19 | 1. Visit the [Firefox Add-ons Store](https://addons.mozilla.org/en-GB/firefox/addon/scrapegraphai-extension/) 20 | 2. Click "Add to Firefox" 21 | 3. Follow the installation prompts 22 | 23 | Watch our [video tutorial](https://www.youtube.com/watch?v=tSy8udRu1lA) for a step-by-step guide on Firefox installation. 24 | 25 | ### 2. Manual Installation (Development Build) 26 | 27 | 1. Download the latest `scrapegraphai_extension.zip` from the [Releases page](https://github.com/ScrapeGraphAI/scrapegraphai-browser-extension/releases) 28 | 2. Extract the ZIP file to a folder on your computer 29 | 3. For Chrome/Chromium browsers: 30 | - Go to `chrome://extensions/` 31 | - Enable "Developer mode" using the toggle in the top-right corner 32 | - Click "Load unpacked" 33 | - Select the extracted folder 34 | 4. For Firefox: 35 | - Go to `about:debugging#/runtime/this-firefox` 36 | - Click "Load Temporary Add-on" 37 | - Select the `manifest.json` file from the extracted folder 38 | 39 | ### 3. Building from Source 40 | 41 | If you want to build the extension from source: 42 | 43 | 1. Clone the repository: 44 | ```bash 45 | git clone https://github.com/ScrapeGraphAI/scrapegraphai-browser-extension.git 46 | cd scrapegraphai-browser-extension 47 | ``` 48 | 49 | 2. Install dependencies: 50 | ```bash 51 | npm install 52 | ``` 53 | 54 | 3. Build the extension: 55 | ```bash 56 | npm run build:chromium # For Chrome/Chromium browsers 57 | # or 58 | npm run build:firefox # For Firefox browser 59 | ``` 60 | 61 | 4. The built extension will be in the `dist` folder 62 | 5. Load it in your browser following the steps from Manual Installation section 63 | 64 | ## Usage 65 | 66 | 1. **Setup** 67 | - After installing the extension, click on its icon in your browser's toolbar 68 | - Go to Settings and enter your ScrapeGraphAI API key 69 | - If you don't have an API key, get one from [ScrapeGraphAI website](https://scrapegraphai.com/) 70 | 71 | 2. **Basic Usage** 72 | - Navigate to any webpage you want to scrape 73 | - Click the extension icon 74 | - Enter your scraping instructions in the text field 75 | - Click "Scrape" to start the process 76 | 77 | 3. **Advanced Options** 78 | - Use "Custom URL" if you want to scrape a different page than the current one 79 | - The extension will notify you when the scraping is complete 80 | - Check your ScrapeGraphAI dashboard and dowload folder for the scraped data 81 | 82 | 4. **Tips** 83 | - Be specific in your scraping instructions 84 | - Make sure you have a valid API key 85 | - Check the extension's status indicators for any errors 86 | 87 | ## Debugging 88 | 89 | For development and debugging: 90 | 91 | ### Install dependencies 92 | 93 | ```bash 94 | npm i 95 | ``` 96 | 97 | ### Build extension 98 | 99 | ```bash 100 | npm run build:chromium 101 | ``` 102 | 103 | ### Load extension on browser 104 | 105 | After building the extension, a `dist` folder will be generated in the root of the project. To load the extension in browser for testing, follow [this guide](https://developer.chrome.com/docs/extensions/get-started/tutorial/hello-world#load-unpacked) and select the `dist` folder. 106 | -------------------------------------------------------------------------------- /scripts/zip.js: -------------------------------------------------------------------------------- 1 | import { createWriteStream } from 'fs'; 2 | import archiver from 'archiver'; 3 | import path from 'path'; 4 | 5 | async function zipDistFolder() { 6 | const output = createWriteStream(path.resolve('scrapegraphai_extension.zip')); 7 | const archive = archiver('zip', { zlib: { level: 9 } }); 8 | 9 | output.on('close', () => { 10 | console.log(`Success! zip file created. Size: ${archive.pointer()} byte`); 11 | }); 12 | 13 | archive.on('error', (err) => { 14 | throw err; 15 | }); 16 | 17 | archive.pipe(output); 18 | 19 | archive.directory(path.resolve('dist'), false); 20 | 21 | await archive.finalize(); 22 | } 23 | 24 | zipDistFolder().catch((err) => console.error('Error during zip file creation:', err)); 25 | -------------------------------------------------------------------------------- /src/assets/css/style.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | body { 6 | width: 500px; 7 | height: 500px; 8 | margin: 0; 9 | } 10 | -------------------------------------------------------------------------------- /src/assets/scrapegraphai_logo.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/components/CreditsInfo.jsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState, useCallback } from 'react'; 2 | import useApiKey from '../hooks/useApiKey'; 3 | import { getCredits } from 'scrapegraph-js'; 4 | 5 | const CreditsInfo = () => { 6 | const [remainingCredits, setRemainingCredits] = useState(null); 7 | const [totalCreditsUsed, setTotalCreditsUsed] = useState(null); 8 | const { apiKey, apiKeyError } = useApiKey(); 9 | 10 | const fetchUserCredits = useCallback(async () => { 11 | if (apiKey && !apiKeyError) { 12 | try { 13 | const credits = await getCredits(apiKey); 14 | setRemainingCredits(credits.remaining_credits); 15 | setTotalCreditsUsed(credits.total_credits_used); 16 | } catch (error) { 17 | console.error('Error checking credits:', error); 18 | } 19 | } 20 | }, [apiKey, apiKeyError]); 21 | 22 | useEffect(() => { 23 | fetchUserCredits(); 24 | }, [fetchUserCredits]); 25 | 26 | return ( 27 | <> 28 | Credits info 29 |
34 | {currentTabUrl.length > 40 35 | ? currentTabUrl.slice(0, 40) + '...' 36 | : currentTabUrl || 'Loading...'} 37 |
38 |{onErrorMessage}
} 28 | > 29 | ); 30 | }; 31 | 32 | TextArea.propTypes = { 33 | value: PropTypes.any.isRequired, 34 | onChange: PropTypes.func.isRequired, 35 | onError: PropTypes.bool, 36 | onErrorMessage: PropTypes.string, 37 | label: PropTypes.string, 38 | rows: PropTypes.number, 39 | placeholder: PropTypes.string, 40 | }; 41 | 42 | export default TextArea; 43 | -------------------------------------------------------------------------------- /src/components/ui/TextField.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | 4 | const TextField = ({ 5 | type, 6 | value, 7 | onChange, 8 | onError = false, 9 | onErrorMessage = '', 10 | label = null, 11 | placeholder = '', 12 | }) => { 13 | return ( 14 | <> 15 | {label && } 16 | 27 | {onError &&{onErrorMessage}
} 28 | > 29 | ); 30 | }; 31 | 32 | TextField.propTypes = { 33 | type: PropTypes.string.isRequired, 34 | value: PropTypes.any.isRequired, 35 | onChange: PropTypes.func.isRequired, 36 | onError: PropTypes.bool, 37 | onErrorMessage: PropTypes.string, 38 | label: PropTypes.string, 39 | placeholder: PropTypes.string, 40 | }; 41 | 42 | export default TextField; 43 | -------------------------------------------------------------------------------- /src/hooks/useAlert.js: -------------------------------------------------------------------------------- 1 | import { useState } from 'react'; 2 | 3 | const useAlert = () => { 4 | const [alert, setAlert] = useState({ 5 | type: null, 6 | message: null, 7 | visible: false, 8 | closeable: true, 9 | }); 10 | 11 | const showAlert = (type, message, closeable = true) => { 12 | setAlert({ type, message, visible: true, closeable }); 13 | }; 14 | 15 | const hideAlert = () => { 16 | setAlert({ ...alert, visible: false }); 17 | }; 18 | 19 | return { alert, showAlert, hideAlert }; 20 | }; 21 | 22 | export default useAlert; 23 | -------------------------------------------------------------------------------- /src/hooks/useApiKey.js: -------------------------------------------------------------------------------- 1 | import { useState, useEffect } from 'react'; 2 | import Browser from 'webextension-polyfill'; 3 | 4 | const useApiKey = () => { 5 | const [apiKey, setApiKey] = useState(''); 6 | const [apiKeyError, setApiKeyError] = useState(null); 7 | 8 | useEffect(() => { 9 | const fetchApiKey = async () => { 10 | try { 11 | const { api_key } = await Browser.storage.local.get('api_key'); 12 | setApiKey(api_key || ''); 13 | if (!api_key) setApiKeyError('No API key found, please set the API key.'); 14 | } catch (error) { 15 | console.error('Error fetching API key:', error); 16 | setApiKeyError('Failed to retrieve API key.'); 17 | } 18 | }; 19 | 20 | fetchApiKey(); 21 | }, []); 22 | 23 | const saveApiKey = async (newApiKey) => { 24 | try { 25 | await Browser.storage.local.set({ api_key: newApiKey }); 26 | setApiKey(newApiKey); 27 | setApiKeyError(null); 28 | } catch (error) { 29 | console.error('Error saving API key:', error); 30 | setApiKeyError('Failed to save API key.'); 31 | } 32 | }; 33 | 34 | return { apiKey, setApiKey, saveApiKey, apiKeyError }; 35 | }; 36 | 37 | export default useApiKey; 38 | -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |