IPLD Explorer Components
React components for https://explore.ipld.io (https://github.com/ipfs/explore.ipld.io) and ipfs-webui
Background
This module was extracted from the explore.ipld.io so it could be reused from the IPFS Web UI.
Usage
WARNING: This module is not intended to be re-used in it's current form by other projects. There is more work to do to make this a nice set of generic components.
Install it from npm:
npm install --save ipld-explorer-components
There are peerDependencies
so that the consuming app can pick the versions of common deps. You'll need to add relevant deps to your project.
Use it in your project
You can see an example of how to use these components in the devPage.jsx file.
import React from 'react'
import {render} from 'react-dom'
import MyHeader from './app'
const PageRenderer = (): React.ReactElement => {
const [route, setRoute] = useState(window.location.hash.slice(1) ?? '/')
useEffect(() => {
const onHashChange = (): void => { setRoute(window.location.hash.slice(1) ?? '/') }
window.addEventListener('hashchange', onHashChange)
return () => { window.removeEventListener('hashchange', onHashChange) }
}, [])
const RenderPage: React.FC = () => {
switch (true) {
case route.startsWith('/explore'):
return <ExplorePage />
case route === '/':
default:
return <StartExploringPage />
}
}
return (
<RenderPage />
)
}
const App = (): React.ReactElement => {
return (
<HeliaProvider>
<ExploreProvider>
<MyHeader />
<PageRenderer />
</ExploreProvider>
</HeliaProvider>
)
}
const rootEl = document.getElementById('root')
if (rootEl == null) {
throw new Error('No root element found with the id "root"')
}
const root = createRoot(rootEl)
root.render(
<I18nextProvider i18n={i18n}>
<App />
</I18nextProvider>
)
Exports provided by this library
import { HeliaProvider, ExploreProvider } from 'ipld-explorer-components/providers'
import { StartExploringPage, ExplorePage } from 'ipld-explorer-components/pages'
import { IpldExploreForm, IpldCarExploreForm } from 'ipld-explorer-components/forms'
import { HeliaProvider, ExploreProvider, StartExploringPage, ExplorePage, IpldExploreForm, IpldCarExploreForm, CidInfo, ObjectInfo } from 'ipld-explorer-components'
The following Components are available:
export {
HeliaProvider,
useHelia,
ExploreProvider,
useExplore,
StartExploringPage,
ExplorePage,
IpldExploreForm,
IpldCarExploreForm,
CidInfo,
ObjectInfo,
}
Styling
And, assuming you are using create-react-app
or a similar webpack set up, you'll need the following CSS imports:
import 'tachyons'
import 'ipfs-css'
import 'ipld-explorer-components/css'
Customizing the links displayed in the StartExploringPage
To customize the links displayed in the start exploring page, you can pass a links
property to the StartExploringPage
component. This property should be an array of objects with the following properties:
{
name: 'Name of your example link',
cid: 'bafyfoo...',
type: 'dag-pb' // or dag-json, etc...
}
i18n support
The translations used for this library are provided in dist/locales
. You can use them in your project by importing them and passing them to the i18n
instance in your project.
import i18n from 'i18next'
import LanguageDetector from 'i18next-browser-languagedetector'
import Backend from 'i18next-chained-backend'
import HttpBackend from 'i18next-http-backend'
import ICU from 'i18next-icu'
import LocalStorageBackend from 'i18next-localstorage-backend'
import { version } from '../package.json'
import locales from './lib/languages.json'
export const localesList = Object.values(locales)
await i18n
.use(ICU)
.use(Backend)
.use(LanguageDetector)
.init({
backend: {
backends: [
LocalStorageBackend,
HttpBackend
],
backendOptions: [
{
defaultVersion: version,
expirationTime: (!import.meta.env.NODE_ENV || imObjectInfo.publicGatewayport.meta.env.NODE_ENV === 'development') ? 1 : 7 * 24 * 60 * 60 * 1000
},
{
loadPath: (lngs, namespaces) => {
const lang = lngs[0]
const ns = namespaces[0]
if (ns === 'explore') {
return 'node_modules/ipld-explorer-components/dist/locales/{{lng}}/{{ns}}.json'
}
return `locales/${lang}/${ns}.json`
}
}
]
},
ns: ['explore', 'app'],
defaultNS: 'app',
fallbackNS: 'explore',
fallbackLng: {
'zh-Hans': ['zh-CN', 'en'],
'zh-Hant': ['zh-TW', 'en'],
zh: ['zh-CN', 'en'],
default: ['en']
},
debug: import.meta.env.DEBUG,
react: {
bindI18n: 'languageChanged loaded',
bindStore: 'added removed',
nsMode: 'default'
}
})
Development
Adding another codec
NOTE: PRs adding an old IPLDFormat codec would need the old blockcodec-to-ipld-format
tool, which has many out-of-date deps. We will only accept PRs for adding BlockCodec interface codecs.
To add another codec, you will need to update all locations containing the comment // #WhenAddingNewCodec
:
- Add a dependency on the codec to this package (if it's not already in multiformats or other package)
- Add the codec in the switch statement in ./src/lib/codec-importer.ts
- Update ./src/lib/get-codec-name-from-code.ts to return the codec name for your codec
- Add a unit test to ./src/lib/resolve-ipld-path.test.js and ensure that calling
resolveIpldPath
returns the expected results
see https://github.com/ipfs/ipld-explorer-components/pull/360#discussion_r1206251817 for history.
Adding another hasher
To add another hasher, you will need to update all locations containing the comment // #WhenAddingNewHasher
:
- Add a dependency on the hasher to this package (if it's not already in multiformats or other package)
- Update ./src/lib/hash-importer.ts
- Update
SupportedHashers
to include your hasher type - Update
getHasherForCode
to return your hasher
- Update the hasher codes used by the
hashers
property passed to Helia init in ./src/lib/init-helia.ts
see https://github.com/ipfs/ipld-explorer-components/pull/395 for an example.
Contribute
Feel free to dive in! Open an issue or submit PRs.
To contribute to IPFS in general, see the contributing guide.
Releasing
License
MIT © Protocol Labs