├── .codesandbox
└── ci.json
├── .editorconfig
├── .github
├── ISSUE_TEMPLATE
│ ├── bug_report.yml
│ └── config.yml
└── workflows
│ └── main.yml
├── .gitignore
├── .husky
├── post-merge
└── pre-commit
├── .prettierignore
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── demo
├── package.json
├── public
│ ├── icons.svg
│ ├── index.html
│ └── vue.svg
├── src
│ ├── App.tsx
│ ├── GitHubRepo.tsx
│ ├── components.tsx
│ ├── index.tsx
│ └── strings.ts
└── tsconfig.json
├── package.json
├── pnpm-lock.yaml
├── sonar-project.properties
├── src
├── config.ts
├── global.d.ts
├── index.tsx
├── modules
│ ├── cache.ts
│ ├── helpers.ts
│ ├── hooks.tsx
│ └── utils.ts
├── provider.tsx
└── types.ts
├── test
├── __fixtures__
│ ├── buttons.svg
│ ├── circles.svg
│ ├── datahref.svg
│ ├── dots.svg
│ ├── icons.svg
│ ├── main.css
│ ├── play.svg
│ ├── react.png
│ ├── react.svg
│ ├── styles.svg
│ ├── styles_with_css_variables.svg
│ ├── tiger.svg
│ └── utf8.svg
├── __setup__
│ ├── global.d.ts
│ └── vitest.setup.ts
├── __snapshots__
│ ├── index.spec.tsx.snap
│ └── unsupported.spec.tsx.snap
├── index.spec.tsx
├── indexWithPersistentCache.spec.tsx
├── modules
│ └── cache.spec.ts
├── tsconfig.json
└── unsupported.spec.tsx
├── tsconfig.json
└── vitest.config.mts
/.codesandbox/ci.json:
--------------------------------------------------------------------------------
1 | {
2 | "sandboxes": ["/demo"],
3 | "node": "18"
4 | }
5 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig is awesome: http://EditorConfig.org
2 |
3 | # top-most EditorConfig file
4 | root = true
5 |
6 | # Unix-style newlines with a newline ending every file
7 | [*]
8 | end_of_line = lf
9 | insert_final_newline = true
10 | indent_style = space
11 | indent_size = 2
12 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.yml:
--------------------------------------------------------------------------------
1 | name: '🐛 Bug report'
2 | description: Report a reproducible bug or regression
3 | body:
4 | - type: markdown
5 | attributes:
6 | value: |
7 | Thank you for reporting an issue :pray:.
8 |
9 | This issue tracker is for reporting reproducible bugs or regression's found in [react-inlinesvg](https://github.com/gilbarbara/react-inlinesvg).
10 | If you have a question about how to achieve something and are struggling, please post a question
11 | inside of react-inlinesvg's [Discussions tab](https://github.com/gilbarbara/react-inlinesvg/discussions).
12 |
13 | Before submitting a new bug/issue, please check the links below to see if there is a solution or question posted there already:
14 | - [Discussions tab](https://github.com/gilbarbara/react-inlinesvg/discussions)
15 | - [Open Issues](https://github.com/gilbarbara/react-inlinesvg/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc)
16 | - [Closed Issues](https://github.com/gilbarbara/react-inlinesvg/issues?q=is%3Aissue+sort%3Aupdated-desc+is%3Aclosed)
17 |
18 | > If you have Typescript errors try upgrading (or maybe downgrading) your version of Typescript and @types/react. This package doesn't have any control over the typescript errors you may be seeing.
19 |
20 | The more information you fill in, the better the community can help you.
21 | - type: textarea
22 | id: description
23 | attributes:
24 | label: Describe the bug
25 | description: Provide a clear and concise description of the challenge you are running into.
26 | validations:
27 | required: true
28 | - type: input
29 | id: link
30 | attributes:
31 | label: Your minimal, reproducible example
32 | description: |
33 | Please add a link to a minimal reproduction.
34 | Note:
35 | - Your bug may get fixed much faster if we can run your code.
36 | - To create a shareable code example for web, you can use CodeSandbox (https://codesandbox.io/s/new) or Stackblitz (https://stackblitz.com/).
37 | - Please make sure the example is complete and runnable - e.g. avoid localhost URLs.
38 | - Feel free to fork the demo CodeSandbox example to reproduce your issue: https://codesandbox.io/s/github/gilbarbara/react-inlinesvg/main/demo
39 | placeholder: |
40 | e.g. Code Sandbox, Stackblitz, etc.
41 | validations:
42 | required: true
43 | - type: textarea
44 | id: steps
45 | attributes:
46 | label: Steps to reproduce
47 | description: Describe the steps we have to take to reproduce the behavior.
48 | placeholder: |
49 | 1. Go to '...'
50 | 2. Click on '....'
51 | 3. Scroll down to '....'
52 | 4. See error
53 | validations:
54 | required: true
55 | - type: textarea
56 | id: expected
57 | attributes:
58 | label: Expected behavior
59 | description: Provide a clear and concise description of what you expected to happen.
60 | placeholder: |
61 | As a user, I expected ___ behavior but i am seeing ___
62 | validations:
63 | required: true
64 | - type: dropdown
65 | attributes:
66 | label: How often does this bug happen?
67 | description: |
68 | Following the reproduction steps above, how easily are you able to reproduce this bug?
69 | options:
70 | - Every time
71 | - Often
72 | - Sometimes
73 | - Only once
74 | - type: textarea
75 | id: screenshots_or_videos
76 | attributes:
77 | label: Screenshots or Videos
78 | description: |
79 | If applicable, add screenshots or a video to help explain your problem.
80 | For more information on the supported file image/file types and the file size limits, please refer
81 | to the following link: https://docs.github.com/en/github/writing-on-github/working-with-advanced-formatting/attaching-files
82 | placeholder: |
83 | You can drag your video or image files inside of this editor ↓
84 | - type: textarea
85 | id: platform
86 | attributes:
87 | label: Platform
88 | description: |
89 | If the problem is specific to a platform, please let us know which one.
90 | placeholder: |
91 | - OS: [e.g. macOS, Windows, Linux, iOS, Android]
92 | - Browser: [e.g. Chrome, Safari, Firefox, React Native]
93 | - Version: [e.g. 91.1]
94 | - type: input
95 | id: rswp-version
96 | attributes:
97 | label: react-inlinesvg version
98 | description: |
99 | Please let us know the exact version of react-inlinesvg you were using when the issue occurred. Please don't just put in "latest", as this is subject to change.
100 | placeholder: |
101 | e.g. 4.0.0
102 | validations:
103 | required: true
104 | - type: input
105 | id: ts-version
106 | attributes:
107 | label: TypeScript version
108 | description: |
109 | If you are using TypeScript, please let us know the exact version of TypeScript you were using when the issue occurred.
110 | placeholder: |
111 | e.g. 5.1.0
112 | validations:
113 | required: true
114 | - type: input
115 | id: build-tool
116 | attributes:
117 | label: Build tool
118 | description: |
119 | If the issue is specific to a build tool, please let us know which one.
120 | placeholder: |
121 | e.g. webpack, vite, rollup, parcel, create-react-app, next.js, etc.
122 | - type: textarea
123 | id: additional
124 | attributes:
125 | label: Additional context
126 | description: Add any other context about the problem here.
127 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------
1 | blank_issues_enabled: false
2 | contact_links:
3 | - name: 🗣 Feature Request / Question / Help
4 | url: https://github.com/gilbarbara/react-spotify-web-playback/discussions/new
5 | about: How does it work with...? I have an idea...
6 |
--------------------------------------------------------------------------------
/.github/workflows/main.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 |
3 | on:
4 | push:
5 | branches: ['main']
6 | tags: ['v*']
7 | pull_request:
8 | branches: ['*']
9 |
10 | workflow_dispatch:
11 |
12 | concurrency:
13 | group: ${{ github.ref }}
14 | cancel-in-progress: true
15 |
16 | jobs:
17 | main:
18 | name: Validate and Deploy
19 | runs-on: ubuntu-latest
20 |
21 | env:
22 | CI: true
23 |
24 | steps:
25 | - name: Setup timezone
26 | uses: zcong1993/setup-timezone@master
27 | with:
28 | timezone: America/Sao_Paulo
29 |
30 | - name: Setup repo
31 | uses: actions/checkout@v4
32 |
33 | - name: Setup Node
34 | uses: actions/setup-node@v4
35 | with:
36 | node-version: 22
37 | registry-url: 'https://registry.npmjs.org'
38 |
39 | - name: Install pnpm
40 | uses: pnpm/action-setup@v4
41 | with:
42 | version: 9
43 | run_install: false
44 |
45 | - name: Get pnpm store directory
46 | shell: bash
47 | run: |
48 | echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
49 |
50 | - name: Setup pnpm cache
51 | uses: actions/cache@v4
52 | with:
53 | path: ${{ env.STORE_PATH }}
54 | key: "${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}"
55 | restore-keys: |
56 | ${{ runner.os }}-pnpm-store-
57 |
58 | - name: Install Packages
59 | run: pnpm install
60 | timeout-minutes: 3
61 |
62 | - name: Validate
63 | if: "!startsWith(github.ref, 'refs/tags/')"
64 | run: pnpm run validate
65 | timeout-minutes: 3
66 |
67 | - name: SonarCloud Scan
68 | if: "!startsWith(github.ref, 'refs/tags/')"
69 | uses: SonarSource/sonarqube-scan-action@master
70 | env:
71 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
72 | SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
73 |
74 | - name: Publish Package
75 | if: startsWith(github.ref, 'refs/tags/')
76 | run: npm publish
77 | env:
78 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
79 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 | .tmp/
3 | coverage/
4 | dist/
5 | node_modules/
6 |
--------------------------------------------------------------------------------
/.husky/post-merge:
--------------------------------------------------------------------------------
1 | ./node_modules/.bin/repo-tools install-packages
2 |
--------------------------------------------------------------------------------
/.husky/pre-commit:
--------------------------------------------------------------------------------
1 | ./node_modules/.bin/repo-tools check-remote && npm run validate
2 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | coverage
2 | esm
3 | lib
4 | node_modules
5 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing to react-inlinesvg
2 |
3 | :+1::tada: First off, thanks for taking the time to contribute! :tada::+1:
4 |
5 | **Reporting Bugs**
6 | Before creating bug reports, please check this [list](https://github.com/gilbarbara/react-inlinesvg/issues) as you might find out that you don't need to create one. When you are creating a bug report, please include as many details as possible.
7 |
8 | **Pull Requests**
9 | Before submitting a new pull request, open a new issue to discuss it. It may already been implemented but not published or we might have found the same situation before and decide against it.
10 |
11 | In any case:
12 |
13 | - Format files using these rules [EditorConfig](https://github.com/gilbarbara/react-inlinesvg/blob/master/.editorconfig)
14 | - Follow the [ESLint](https://github.com/gilbarbara/react-inlinesvg/blob/master/.eslintrc) styleguide.
15 |
16 | Thank you!
17 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2014, Matthew Dapena-Tretter / Gil Barbara
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining
6 | a copy of this software and associated documentation files (the
7 | "Software"), to deal in the Software without restriction, including
8 | without limitation the rights to use, copy, modify, merge, publish,
9 | distribute, sublicense, and/or sell copies of the Software, and to
10 | permit persons to whom the Software is furnished to do so, subject to
11 | the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be
14 | included in all copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # react-inlinesvg
2 |
3 | [](https://www.npmjs.com/package/react-inlinesvg) [](https://github.com/gilbarbara/react-inlinesvg/actions/workflows/main.yml) [](https://sonarcloud.io/summary/new_code?id=gilbarbara_react-inlinesvg) [](https://sonarcloud.io/summary/new_code?id=gilbarbara_react-inlinesvg)
4 |
5 | Load inline, local, or remote SVGs in your React components.
6 |
7 | View the [demo](https://codesandbox.io/s/github/gilbarbara/react-inlinesvg/tree/main/demo)
8 |
9 | ## Highlights
10 |
11 | - 🏖 **Easy to use:** Just set the `src`
12 | - 🛠 **Flexible:** Personalize the options to fit your needs
13 | - ⚡️ **Smart:** Async requests will be cached.
14 | - 🚀 **SSR:** Render a loader until the DOM is available
15 | - 🟦 **Typescript:** Nicely typed
16 |
17 | ## Usage
18 |
19 | ```sh
20 | npm i react-inlinesvg
21 | ```
22 |
23 | And import it into your code:
24 |
25 | ```tsx
26 | import React from 'react';
27 | import SVG from 'react-inlinesvg';
28 |
29 | export default function App() {
30 | return (
31 |
32 |
38 |
39 | );
40 | }
41 | ```
42 |
43 | ## Props
44 |
45 | **src** {string} - **required**.
46 | The SVG file you want to load. It can be a require, URL, or a string (base64 or URL encoded).
47 | _If you are using create-react-app and your file resides in the `public` directory, you can use the path directly without require._
48 |
49 | **baseURL** {string}
50 | An URL to prefix each ID in case you use the `` tag and `uniquifyIDs`.
51 |
52 | **children** {ReactNode}
53 | The fallback content in case of a fetch error or unsupported browser.
54 |
55 | ```
56 |
59 | ```
60 |
61 | **cacheRequests** {boolean} ▶︎ `true`
62 | Cache remote SVGs.
63 | Starting in version 4.x, you can also cache the files permanently, read more [below](#caching).
64 |
65 | **description** {string}
66 | A description for your SVG. It will override an existing `` tag.
67 |
68 | **fetchOptions** {RequestInit}
69 | Custom options for the [request](https://developer.mozilla.org/en-US/docs/Web/API/Request/Request).
70 |
71 | **innerRef** {React.Ref}
72 | Set a ref in SVGElement.
73 |
74 | >The SVG is processed and parsed so the ref won't be set on the initial render.
75 | You can use the `onLoad` callback to get and use the ref instead.
76 |
77 | **loader** {node}
78 | A component to be shown while the SVG is loading.
79 |
80 | **onError** {function}
81 | A callback to be invoked if loading the SVG fails.
82 | This will receive a single argument with:
83 |
84 | - a `FetchError` with:
85 |
86 | ```typescript
87 | {
88 | message: string;
89 | type: string;
90 | errno: string;
91 | code: string;
92 | }
93 | ```
94 |
95 | - or an `InlineSVGError`, which has the following properties:
96 |
97 | ```typescript
98 | {
99 | name: 'InlineSVGError';
100 | data: object; // optional
101 | message: string;
102 | }
103 | ```
104 |
105 | **onLoad** {function}.
106 | A callback to be invoked upon successful load.
107 | This will receive 2 arguments: the `src` prop and an `isCached` boolean
108 |
109 | **preProcessor** {function} ▶︎ `string`
110 | A function to process the contents of the SVG text before parsing.
111 |
112 | **title** {string | null}
113 | A title for your SVG. It will override an existing `` tag.
114 | If `null` is passed, the `` tag will be removed.
115 |
116 | **uniqueHash** {string} ▶︎ a random 8 characters string `[A-Za-z0-9]`
117 | A string to use with `uniquifyIDs`.
118 |
119 | **uniquifyIDs** {boolean} ▶︎ `false`
120 | Create unique IDs for each icon.
121 |
122 | > Any additional props will be passed down to the SVG element.
123 |
124 | ### Example
125 |
126 | ```jsx
127 |