├── 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 |
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 |