├── src ├── index.css ├── assets │ ├── openai.png │ └── light-bulb.svg ├── main.jsx ├── components │ ├── Footer.jsx │ ├── Header.jsx │ ├── KeywordsModal.jsx │ └── TextInput.jsx └── App.jsx ├── screenshot.png ├── .env.example ├── vite.config.js ├── .gitignore ├── index.html ├── package.json ├── readme.md └── public └── vite.svg /src/index.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bradtraversy/ai-keyword-extractor/HEAD/screenshot.png -------------------------------------------------------------------------------- /src/assets/openai.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bradtraversy/ai-keyword-extractor/HEAD/src/assets/openai.png -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | VITE_OPENAI_API_KEY='ADD_YOUR_KEY_HERE' 2 | VITE_OPENAI_API_URL='https://api.openai.com/v1/completions' -------------------------------------------------------------------------------- /vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import react from '@vitejs/plugin-react'; 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [react()], 7 | server: { 8 | port: 3000, 9 | }, 10 | }); 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | 26 | .env -------------------------------------------------------------------------------- /src/main.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import App from './App'; 4 | import './index.css'; 5 | import { ChakraProvider } from '@chakra-ui/react'; 6 | 7 | ReactDOM.createRoot(document.getElementById('root')).render( 8 | 9 | 10 | 11 | 12 | 13 | ); 14 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | AI Keyword Generator 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/components/Footer.jsx: -------------------------------------------------------------------------------- 1 | import { Box, Text, Image, Flex } from '@chakra-ui/react'; 2 | import logo from '../assets/openai.png'; 3 | 4 | const Footer = () => { 5 | return ( 6 | 7 | 8 | 9 | Powered By Open AI 10 | 11 | 12 | ); 13 | }; 14 | export default Footer; 15 | -------------------------------------------------------------------------------- /src/components/Header.jsx: -------------------------------------------------------------------------------- 1 | import { Heading, Image, Text } from '@chakra-ui/react'; 2 | import logo from '../assets/light-bulb.svg'; 3 | 4 | const Header = () => { 5 | return ( 6 | <> 7 | logo 8 | 9 | AI Keyword Extractor 10 | 11 | 12 | Paste in your text below and we'll extract the keywords for you. 13 | 14 | 15 | ); 16 | }; 17 | 18 | export default Header; 19 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ai-keyword-extractor", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "preview": "vite preview" 10 | }, 11 | "dependencies": { 12 | "@chakra-ui/react": "^2.5.2", 13 | "@emotion/react": "^11.10.6", 14 | "@emotion/styled": "^11.10.6", 15 | "framer-motion": "^10.7.0", 16 | "react": "^18.2.0", 17 | "react-dom": "^18.2.0" 18 | }, 19 | "devDependencies": { 20 | "@types/react": "^18.0.28", 21 | "@types/react-dom": "^18.0.11", 22 | "@vitejs/plugin-react": "^3.1.0", 23 | "vite": "^4.2.0" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # AI Keyword Extractor 2 | 3 | This is a simple tool built with React and Chakra UI that uses the Open AI [chat completion API](https://platform.openai.com/docs/guides/completion) to extract the best keywords from any given text. 4 | 5 |
6 | 7 |
8 | 9 | ## How to use 10 | 11 | Install dependencies: 12 | 13 | ```bash 14 | npm install 15 | ``` 16 | 17 | Rename `.env.example` to `.env` and add your API key. You can get your key at [https://platform.openai.com/account/api-keys](https://platform.openai.com/account/api-keys). 18 | 19 | ```bash 20 | VITE_OPENAI_API_KEY='ADD_YOUR_KEY_HERE' 21 | ``` 22 | 23 | Important: Your API key is not secure as there is no backend. If you decide to use this tool in production, you should add a backend to it and store the API key there. 24 | 25 | Run the dev server: 26 | 27 | ```bash 28 | npm run dev 29 | ``` 30 | 31 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. 32 | 33 | To build for production: 34 | 35 | ```bash 36 | npm run build 37 | ``` 38 | 39 | ## License 40 | 41 | MIT License 42 | -------------------------------------------------------------------------------- /src/components/KeywordsModal.jsx: -------------------------------------------------------------------------------- 1 | import { 2 | Text, 3 | Button, 4 | Modal, 5 | ModalOverlay, 6 | ModalContent, 7 | ModalHeader, 8 | ModalFooter, 9 | ModalBody, 10 | ModalCloseButton, 11 | CircularProgress, 12 | } from '@chakra-ui/react'; 13 | 14 | const KeywordsModal = ({ keywords, loading, isOpen, closeModal }) => { 15 | return ( 16 | <> 17 | 18 | 19 | 20 | Keywords 21 | 22 | 23 | {loading ? ( 24 | 25 | ) : ( 26 | {keywords} 27 | )} 28 | 29 | 30 | 31 | 34 | 35 | 36 | 37 | 38 | ); 39 | }; 40 | export default KeywordsModal; 41 | -------------------------------------------------------------------------------- /src/components/TextInput.jsx: -------------------------------------------------------------------------------- 1 | import { useState } from 'react'; 2 | import { Button, Textarea } from '@chakra-ui/react'; 3 | import { useToast } from '@chakra-ui/react'; 4 | 5 | const TextInput = ({ extractKeywords }) => { 6 | const [text, setText] = useState(''); 7 | 8 | const toast = useToast(); 9 | 10 | const submitText = () => { 11 | if (text === '') { 12 | toast({ 13 | title: 'Text field is empty.', 14 | description: 'Please enter some text to extract keywords.', 15 | status: 'error', 16 | duration: 5000, 17 | isClosable: false, 18 | }); 19 | return; 20 | } 21 | 22 | extractKeywords(text); 23 | }; 24 | 25 | return ( 26 | <> 27 |