Google Cloud Vision APIとGakuNin RDMを用いたTEI/XMLファイル作成アプリの試作

概要 Google Cloud Vision APIとGakuNin RDMを用いたTEI/XMLファイル作成アプリを試作しましたので備忘録です。 背景 Google Cloud Vision APIを使ってOCR結果を反映したTEI/XMLファイルを作成する環境が必要になりました。そこでバックエンドとしてGakuNin RDMを用いて、ユーザごとにファイルを管理して、OCRを実行可能な環境を試作しました。 使い方 フォルダの作成 以下にアクセスします。 https://ge-manager.vercel.app/ 画面右上から、GakuNin RDMを使ってログインします。 以下のようにプロジェクト一覧が表示されます。 適当な階層まで下り、フォルダの作成ボタンを押します。 ここでは、「sample」というフォルダを作成します。 そして、「GE Manager」のリンクを押します。 以下のようなページに遷移します。 処理の実行 今回は、「e-codices - Virtual Manuscript Library of Switzerland」の「fragm1a」を使用させていただきます。 https://www.e-codices.unifr.ch/loris/gau/gau-Fragment/gau-Fragment_frag001a.jp2/full/full/0/default/jpg 画像のURLを入力して、アップロードボタンを押します。アップロードされると、以下のような画面に変わります。 次に、「OCR実行」ボタンを押します。正しく完了すると、以下のように表示されます。 次に「TEI/XML作成」ボタンを押します。正しく完了すると、以下のようにTEI/XMLとともに表示されます。 Oxygen XML Editorでダウンロードしたファイルを表示した例です。Google Cloud Vision APIによるOCR結果を確認することができます。 GakuNin RDMのファイル 上記のプロセスで作成された各種ファイルは、GakuNin RDMのフォルダにファイルとして保存されます。 参考: URLを介してアクセス可能な画像ファイルを用意する mdx.jpのオブジェクトストレージを利用して、URLを介してアクセス可能な画像ファイルを用意する。 今回はge-editorというバケットを作成し、以下のようなファイルを用意します。 { } " " ] V S e t { } r a s t " " " } " " i e S E P , A R o m i f r " c e n e d f i D t s " n " e n D i o : t : c c N o u " t i " n r " : " " p : " c 2 g : a : e 0 [ e l [ " 0 - " " " [ : 8 e A : * " - d l " s " 1 i l { ] 3 g 0 t o : e - o w L - 1 r " i e 7 " , s d " , t i , B t u o c r k " e t " , " s 3 : G e t O b j e c t " ] , そして、以下を実行することで、上記のバケットにアップロードされたファイルをダウンロード可能にします。 ...

2025年4月16日 · 2 分 · Nakamura

「れきちず x Next.js」サイトにルートの登録機能を追加しました。

概要 「れきちず x Next.js」サイトにルートの登録機能を追加しました。以下が表示例です。 参考 「れきちず x Next.js」サイトについては、以下で紹介しています。 この「れきちず」を使ってルートを表示する先行事例として、以下が挙げられます。 https://codh.rois.ac.jp/edomi/route/ 今回は上記の事例を参考に、ルートを作成する機能を追加しました。 使い方 サイトにアクセスします。 https://rekichizu-next.vercel.app/ja/ 「マイルートを管理」をクリックします。 ログインが求められますので、画面右上のボタンからログインします。 「新しいルートを作成」から、ルートを作成します。 以下が編集画面です。 編集アイコンをクリックすると、ルートのタイトルおよび説明を編集できます。 モードを「追加」に設定すると、地図上でクリックした箇所にピンが立ちます。ドラッグ&ドロップで移動させることも可能です。 マーカーはドラッグ&ドロップで順序変更することができます。 インポートとエクスポート エクスポート ルートの一覧画面と編集画面にダウンロードボタンを設置しています。以下のようなJSONファイルがダウンロードされます。 { } " " ] t f y e { } { } { } p a , , e t " " } " } " " } " } " " } " } " u t p , g t p , g t p , g : r y r " " " " e " " ] y r " " " " e " " ] y r " " " e " " ] e p o i t w t o t c p o i t w t o t c p o i p t o t c " s e p d e h y m y o 1 3 e p d e h y m y o 1 3 e p d a y m y o [ ] [ ] F " " e " x e p e p o 3 5 " e " x e p e p o 3 5 " e " t p e p o , e : : r : t r e t e r 9 . : r : t r e t e r 9 . : r : h e t e r 1 3 1 3 a t " e " r " d . 7 t " e " r " d . 7 t " " r " d 3 5 3 5 t [ " i " : " : y : i 7 0 " i " : " : y : i 7 1 " i " : : y : i 9 . 9 . u F e 1 : " n 6 7 F e 1 : " n 7 2 F e 1 " n . 7 . 7 r e s 7 " " : " a 8 7 e s 7 " " : " a 0 1 e s 7 " " : " a 7 0 7 1 e a " 4 湯 " p P t 0 0 a " 4 不 " p P t 5 0 a " 4 [ l L t 6 7 7 2 C t : 4 島 神 o { o e 9 2 t : 4 忍 池 o { o e 0 4 t : 4 1 i { i e 8 7 0 1 o u 6 天 社 i i s 9 0 u 6 池 " i i s 6 9 u 6 7 n n s 0 0 5 0 l r { 3 神 " n n " 2 1 r { 3 " , n n " 8 9 r { 3 4 e e " 9 2 0 4 l e 9 " , t t : 1 3 e 9 , t t : 1 4 e 9 4 " S : 9 0 6 9 e " 5 , " " 4 8 " 3 " " 0 9 " 5 6 t 2 1 8 9 c , 5 , [ 7 1 , 7 , [ 3 6 , 5 3 r [ 1 3 1 4 t 1 0 7 9 4 9 1 9 i 4 8 0 9 i 5 0 1 9 1 1 5 5 n 7 1 3 6 o 6 5 5 0 0 5 6 5 g 0 7 4 9 n 3 6 5 3 3 3 1 " 0 1 1 1 " " , " , - 5 , 5 5 0 5 , , , 1 6 6 5 3 7 3 , , 4 ] 4 6 3 9 3 [ 7 1 9 7 9 4 0 4 3 6 " 3 , 9 3 7 9 9 0 3 ] " , これをgeojson.ioに貼り付けると、以下のように表示されます。 ...

2025年4月14日 · 4 分 · Nakamura

れきちずをNext.jsで使用する

概要 れきちずをNext.jsで使用する方法を調べてみましたので、備忘録です。 背景 以下の記事で、「れきちず」の使い方を紹介しました。 そして、2025年4月4日に「全国版が公開」されたことを知りました。 https://rekichizu.jp/ そこでNext.jsを用いて作成したアプリケーションへの導入にあたり、その使い方を調べてみました。 デモアプリ 以下のようなアプリケーションを試作しました。 https://rekichizu-next.vercel.app/ja/ 使用方法の調査にあたり、公式サイトで提供されている地図の切り替えや重ね合わせ機能、および検索機能などを再現することを目的としました。この実装にあたり、以下のReactライブラリを使用しました。 https://visgl.github.io/react-maplibre/ 開発メモ 検索機能 検索機能には、GeoLODのAPIを利用させていただきました。なお、「れきちず」の公式サイトでは、専用の検索APIが用いられているようでした。 https://geolod.ex.nii.ac.jp/doc/api/ react-maplibre 本ライブラリを使用して、やりたいことの多くを実現できました。一方、TerrainControlではTerrainのON/OFFと合わせてピッチを変更することが難しい?、useMapではaddLayer/removeLayerが難しい?など、いくつか苦労した点もありました。 まとめ 「れきちず」およびNext.jsを用いたアプリケーション開発にあたり、参考になりましたら幸いです。 「れきちず」の開発に関わる方々に深く感謝いたします。

2025年4月9日 · 1 分 · Nakamura

IIIF画像に対して、多角形のアノテーションを付与するツールを作成しました。

概要 IIIF画像に対して、多角形のアノテーションを付与するツールを作成しました。 https://next-fb-anno.vercel.app/ 本記事では、このツールについて説明します。 使い方 以下がトップ画面です。IIIFマニフェストファイルのURLを入力します。「入力例を使用」からもお試しいただけます。『百鬼夜行図』(東京大学総合図書館所蔵)を使用しています。 以下のようなアノテーション登録画面が表示されます。 画面右上のログインボタンからログインできます。 アノテーション付与の方法は、以下の動画を参考にしてください。 https://youtu.be/9RMqaXTaOzE 開発した背景 以下の記事で説明したように、Mirador 3の mirador-annotations プラグイン向けに、Firestore用のアダプタを開発しました。 このmirador-annotations プラグインについて、多角形のアノテーション付与を行いづらいという意見がありました。 そこで、主に多角形のアノテーション付与を支援するために、本ツールを開発しました。また、アノテーション付与を実装するためのライブラリであるAnnotoriousについて、Reactライブラリが公開されていたので、この調査も兼ねて実装しました。 https://annotorious.dev/react/openseadragon-iiif/ さらに、上記の記事で紹介したmirador-annotations プラグインのFirestore用のアダプタを流用することで、同じFirebaseのサービス(AuthenticationとFirestore)を使用するようにしました。 そのため、本ツールの右上のボタンに、Miradorへのリンクを付与しました。 これにより、本ツールで編集を行い、IIIFマニフェストファイルのメタデータを含む、情報の表示にはMiradorを使用する、といった使い方が可能になるかと思います。 多角形のアノテーションを付与するための既存ツール IIIF画像に対してアノテーションを付与する機能を持つ既存ツールは数多く存在します。ここでは、IIIF画像に対して多角形のアノテーションを付与する機能を有するツールと、本ツールとの差分を紹介します。 ここでは、国立国会図書館で公開されている「和泉国絵図」を例とします。 Omeka Classic + IIIF Toolkit 以下の記事でセットアップ方法や使い方を紹介しています。 https://zenn.dev/nakamura196/books/2a0aa162dcd0eb IIIF Toolkitでは、Mirador 2が使用されており、ポリゴンアノテーションが提供されています。 今回にニーズに対しては、多角形アノテーションではなくポリゴンアノテーションである点と、Omeka Classicのセットアップ(サーバの準備や維持)が必要になる点が課題として挙げられます。 Recogito Recogitoでは傾斜したボックス形式のアノテーションを付与することはできましたが、多角形のアノテーション付与はできないようでした。 また、以下のように、pctを用いてIIIF画像にアクセスするようで、画像が表示できないケースが多くありました。 Glycerine: Image Annotation Workbench 本ツールが最も今回のニーズに合致していました。 https://glycerine.io/ おそらく本ツールと同じ「Annotorious(のver.2)」が使用されており、多角形によるアノテーションのほか、複数人による共同作業も可能でした。 唯一の課題として、登録したアノテーションの一括登録機能が提供されていませんでした。この点に対して、今回開発したツールでは、読み込んだIIIFマニフェストファイルに対して、ログインユーザが登録したユーザが付与したアノテーションを一括エクスポートする機能を設けました。 これにより、本ツールで付与したアノテーションを一括エクスポートし、他の可視化ツールで使用する、といった使い方が容易になります。 なお、以下の記事で紹介したように、Mirador 3の mirador-annotations プラグインにも付与したアノテーションをダウンロードする機能が提供されています。しかい、この機能はCanvasごとにダウンロードする仕様となっており、複数ページから構成される場合には、ページごとにダウンロードする必要がありました。 工夫点および開発メモ 本ツールの開発にあたり、工夫した点などを紹介します。 入力するIIIFマニフェストのv2およびv3対応 入力するIIIFマニフェストファイルはv2とv3、どちらでも対応できるようにしました。この実現にあたり、以下の記事で紹介した@iiif/parserを使用しました。 ...

2025年4月2日 · 4 分 · Nakamura

Next.js 15 App Router で Tailwind CSS V4 を使用してダークモードを追加する方法

概要 Next.js 15 App Router で Tailwind CSS V4 を使用してダークモードを追加する方法です。 以下の記事が参考になりました。 https://sujalvanjare.vercel.app/blog/dark-mode-nextjs15-tailwind-v4 以下のように、ダークモードとライトモードを切り替えることができました。 上記の記事について、ChatGPTによる日本語記事です。 Next.js 15 App RouterプロジェクトでTailwind CSS V4を使用してダークモードとライトモードを実装する方法を学びましょう。このステップバイステップガイドでは、シームレスなテーマスイッチャーを実現するためのTailwind V4とNext.js 15の最新の変更点をカバーしています! 既にNext.jsプロジェクトをお持ちの場合は、ステップ1に進んでください。 ステップ1:新しいNext.jsプロジェクトを作成する App RouterとTailwind CSS v4を搭載したNext.js 15をインストールするには、次の手順に従ってください: 任意の場所にプロジェクトフォルダを作成します。 VS Codeでフォルダを開きます。 ターミナルを開き、次のコマンドを実行します: npmユーザーの場合: n p x c r e a t e - n e x t - a p p @ l a t e s t . pnpmユーザーの場合: p n p x c r e a t e - n e x t - a p p @ l a t e s t . インストール中に、次のオプションが表示されます: ...

2025年4月1日 · 20 分 · Nakamura

Error: Do not use <img>. Use Image from 'next/image' instead.への対応

概要 Error: Do not use . Use Image from ’next/image’ instead.への対応にあたり、以下の記事が参考になりました。 https://stackoverflow.com/questions/68203582/error-do-not-use-img-use-image-from-next-image-instead-next-js-using-ht 上記の記事に基づき、ChatGPTによる回答を以下に掲載します。間違っている点もあるかもしれませんが、参考になりましたら幸いです。 Next.jsのESLintルール変更とフラットコンフィグの設定方法 Next.js 11以降、ESLintの設定がデフォルトで提供されるようになり、@next/next/no-img-element ルールが追加されました。このルールにより、通常の<img>タグの使用が制限され、Next.jsのnext/imageコンポーネントを推奨するようになっています。 しかし、プロジェクトによっては<img>タグを使いたい場合もあるでしょう。そのため、このESLintルールを無効化する方法を紹介します。 1. 従来の設定方法(.eslintrc.js) 以前のNext.jsのESLint設定は、.eslintrc.js に次のように記述することで変更できました。 m } o ; d r } u u , l l " e e @ . s n e : e x x p { t o / r n t e s x t = / n { o - i m g - e l e m e n t " : " o f f " , しかし、Next.jsのESLintは「フラットコンフィグ(Flat Configuration)」へ移行しました。そのため、.eslintrc.js ではなく、eslint.config.mjs を使用する必要があります。 ...

2025年4月1日 · 3 分 · Nakamura

CETEIceanとXPathを使って特定の要素にスクロールする

概要 CETEIceanとXPathを使って特定の要素にスクロールする方法を調べたので備忘録です。 デモ 以下のURLからお試しいただけます。 https://next-ceteicean-router.vercel.app/xpath/ ページにアクセス後、スクロールし、以下のように表示されます。 XPathの取得 上記では、以下の「校異源氏物語テキストDB」のXMLファイルを対象にしています。 https://kouigenjimonogatari.github.io/tei/01.xml そして、以下のXPathを指定しています。 /TEI/text[1]/body[1]/p[1]/seg[267] このXPathの取得にあたっては、Oxygen XML Editorを用いて、対象要素を右クリックして、「Copy XPath」から取得することができました。 スクロールの実装 以下で紹介したアプリをベースにします。 GitHub上のソースコードは以下です。 https://github.com/nakamura196/next-ceteicean-router/blob/main/src/components/xpath/Render.tsx 特に以下の部分で、XPathをCETEIceanによって作成される要素名に変換し、scrollIntoViewによってスクロールしています。 R } f e , e a c c i } t c o o f [ c t n n . . . c ) c i } t h . s s r r t ( o ; o f e D u t t e e o t n x t n X n n t } t i a s p p L e s p e u P u s ( a ) a D t e r x l l o i t a i l a l t t r b b i ; r o a E a p a a w C t C l t l a g e l n g c の f w a c c e o r h o , h t r e h o l e ] 修 f X t e e r n e , n R a g t a c i t ) 正 e p h ( ( C t s t e r e E v k n E ; c a / / a e u e s g t l i : e l t t = ( s n l n u e E e o : e ( h [ e t t t l t l m r " m ( r A ( R R t E e e : c " e ) = a / - ) e = e . l m n e c n w , Z ; f f F e e t " n e t = " X a . d . I m n . s t n . > / p " - c o c R e t s m e t s T a " z u c u S n ) c o r e t { E t ) ] r u r T t r o " r y I h r m r _ { o t , " l / e e e O = l h , e t ( n n n R l " . e ? t t t D r I , b x 先 = ) . , E e n a t 頭 \ e R s t c [ の / { v E u o k 1 ス | a D l V g ] ラ \ l _ t i r / ッ [ u N . e o b シ | a O s w u o ュ $ t D i ( n d を ) e E n { d y 削 / ( _ g C [ 除 g T l o 1 , Y e l ] P N o / " E o r p t , d [ e e = 1 i V ] - a " / $ l y s 1 u e e " e l g ) l [ a o 2 s w 6 " 7 H ; ] t T " e M ; i L - E プ l レ e フ m ィ e ッ n ク t ス ; を 追 加 まとめ 他にも良い方法があるかもしれませんが、参考になりましたら幸いです。 ...

2025年3月27日 · 3 分 · Nakamura

Next.jsでUniversal Viewerのnpmパッケージを使用する

概要 Next.jsでUniversal Viewerのnpmパッケージを使用する方法の備忘録です。 インストール 以下でインストールします。 n p m i u n i v e r s a l v i e w e r 実装 useEffectを使うため、クライアントコンポーネントとして実装する必要があるようでした。 またdivタグにuvクラスを与えることで、cssが当たるようになりました。 ' i i i } f } c } e u m m n u o ) x s p p t m c x n u } r n s l ) p e o o e a v y コ c s , e S s s o , o r r r n ? w ン t e c r i t < S t r a < r c t t f i : h ポ i E o e n [ u d R : d d / t l a f ? ー o f n q i m r i を V i i s } ビ d i { d c e n : ネ n f u s u t a n v 無 i f n v t } ュ i d e y e s u ン e n t i ( n 効 e a g y w h d j a b ー v e n u n t m s ト V c i r ' i ( i 化 w l : l i e i u l a ワ > f t s a V : b t の i t v { e u f d し e s e d i s s i c ー a ' e m i e r 実 e ( e ( v e = 、 r e = t g p t g k を u E i e s r i 装 w ( r i ' ' s " ク , { h h l i n g 読 l f c w t n e ) s n u , t u ラ = { : t a f I r み t f e r g r a i n , v イ = : y y t o 込 e f r i C = l t i { " ア d > ' : C e u み V c r P n o > v v c ン y 1 ' o m n 中 i t o r g m i } e m v c ト n 0 6 ' n s d . e m o p { e r a , l サ a 0 0 f t : : . w } p o w = s n a イ m % v l e . e ' s n e a i x s ド i ' h e n ' ' r f n e r r l f y s で c , ' x t c # r e { n を e v e w N の ( , ' : e f o x t イ q i s h a み ( , n 0 m t ( ン u e t ] m レ ) ' t f { ポ i w , ) e ン c e 0 ' d ー r e = ダ = e r f r y m ト e r c " リ > n ' 0 e n a し ( a u ン t , ' a a n て ' d n v グ P e , c m i 初 u i v " す r r t i f 期 n s a る o ' ' c e 化 i t s s コ m , ' s v / I t ン i t e e n y ポ s , r s d l ー e s m e e ネ . c a / x = ン r v l i : { ト e , v n { s i d c o x e e v w l y w x , i v w e . d e h r c x t ( ' s y h V } ) s w : i : ' h e ) ' w V } 1 e i ) 0 r e 0 C w % o e ' m r , p P o r h n o e e p i n s g t ) h ) t , { : { ' 6 0 v h ' } } > < / d i v > 他にも使用可能なオプションがあるかと思いますが、cvで処理ロードするcanvasのインデックス、xywhで表示する矩形を指定することができました。 ...

2025年3月23日 · 4 分 · Nakamura

GakuNin RDMのAPIを用いて、連携したストレージのファイルを検索する

概要 以下の記事で、GakuNin RDMのAPIを用いたアプリケーション構築について紹介しました。 本記事では、GakuNin RDMのAPIを用いて、連携したストレージのファイルを検索する方法を紹介します。 実装例 次のような形で、検索APIを実装しました。なお、https://rdm.nii.ac.jp/api/v1/search/file/にクライアントから直接アクセスした際には、CORSによるエラーが発生したため、Next.jsのAPI Routesとして実装しています。 i i i e } m m m x p p p p c c c c c c c c } c } c r o o o o o o o o o o o o ; o ) o e r r r r n n n n n n n n a s h e } n m h } b ; n t t t t t s U s s s s s s s p o i l , s e e , o s u t R t t t t t t t i r g a q } f s t t a " A d t r { { { a L _ t h s u , r i h d C u y n s s か u q o s a a p v : l t e f } o z r o e o t : d N a g y e ら r u f i c p a e i i r i , m e e d r n h a N e u e n s ク l e f z c i r r " g c y l q } : , s : s t o J t e x t t c s エ r s e e U a s c h s : t u , : e r S a x t h S i リ = y e s r m i r t e e e q } o = " n i O t R O e f o パ t = s l s o e : a { r r u , f P { t z N = R e p r u n ラ n = T n a r e y e d f ] q a l f a O - a . e s t v n メ e = p o = = : t " c d : r e i , u n e s w S T t s a s p i e c = ー w u a k e t h : y f e " " " " " " " e a n e a T y i t w p o o r t タ r p r e " { { d i _ { _ a l _ t d j s a a r l i t i " p o r a o n n S i a を U l a s n h _ t d { s u d a i e o c l l y y e , t , e n i i n s s e o w 取 R . r e t v d l s t l s l t s b h l l , z n " : n t s e s n a 得 L s s I = t e e e l r t : l l c ^ o _ _ e t f : g e } s i ( e e n p n s : : i _ " e r 1 o j s _ : e ` i r . } i G t r a I t s s d c 3 n f [ , ^ i " l o c w t " B f e j f o E e r n ( e : o " 0 { g i 4 p , ^ b h i t c a e y s s f r n T g q c t u s / r , , : e " t 1 s o l r h p a ( . o r o ( e . h ( r s / : n l , i " ^ o d u ( p r p j n o m } r t u P u l i r a { d o , 0 l c e a l e a s ( m e S r a r . o d " m : n . s a , p i r r o d " f q e l r l s n m g e ^ 1 ^ r i c a n a " @ r : r ) a . e ? . r : " 1 2 0 d U a $ m ( t n / o v ; m s a . n d 3 _ . 5 . : r t { s ) a e a m R e s e r a i m 0 a 2 " 1 l i a ) ; ) x p e r . a c c i " , l " , 2 t , o c , ; t p " q S g r h c . , u l , 5 r n c / / n u e e c P e a s " " u { / e s a e e s t h a s c v e , , e j s e p x s s ( P r s . e r , s s r i t t i " a a T j r : o T v / - ) o f r m o p s 3 n o e a a n i a s k / i 0 " k r u u { ( l m . e a o , , e " t t a t s g n p n t n ; h h u e . e ; i : e } / " t r g t / x ` [ ; h [ e ( v 2 t , . O f t " 1 : . p u ( p / } 1 . t l " a s , 2 n i l p g e 4 e o t a e a , x n e g [ r c t s x e l c o a ) t [ i h m u ; ] o m / m t " f i f e h ) f t i n ] s ] l t / e " e s a t ) / . u ] " * t " " ; : h " 1 O ; 2 p " 4 t 2 " i 0 , o " " n 0 , s " " , 1 ; 0 1 ) 0 ; ) ; 利用例 以下のURLからお試しいただけます。(利用にあたっては、GakuNin RDMへのログインが必要です。) ...

2025年3月21日 · 11 分 · Nakamura

LEAF WriterとGakuNin RDMを用いたTEI/XMLファイルの編集環境の試作

概要 LEAF WriterとGakuNin RDMを用いたTEI/XMLファイルの編集環境の試作を行いましたので、備忘録です。 参考 以下の記事で、LEAF WriterをNext.jsから使用する方法を紹介しました。 特に、以下のnpmパッケージを使用しています。 https://www.npmjs.com/package/@cwrc/leafwriter 上記で編集対象とするTEI/XMLファイルの入出力にあたり、GakuNin RDMを使用してみます。GakuNin RDMのAPIをJavaScriptから使用する方法について、以下も参考になりましたら幸いです。 使い方 以下がプロトタイプシステムのURLです。(色々と不具合が含まれる点にご注意ください。) https://rdm-leaf-editor.vercel.app/ UIはClaude 3.7 Sonnetに作成してもらっています。 「サインイン」ボタンを押すと、認証画面に進むので、ログインします。 ログイン後、リダイレクトされ、プロジェクトの一覧が表示されます。 TEI/XMLファイルが含まれるディレクトリまで移動します。ファイル名に「.xml」が含まれる場合、「Leaf Writer」の列に「編集」ボタンが表示されます。 LEAF Writerの編集画面に遷移するので、テキストを編集します。作業が完了したら、画面右上の「保存」ボタンを押します。 GakuNin RDMのUIから確認してみると、バージョンごとに保存されていることが確認できます。 実装 GakuNin RDMからのファイルの取得および更新は以下で行っています。 e ) } e ) } x : x : p u a c } i } r p u c a c c c } i } フ o r c P o ) f e フ o r o c o P o o ) f ァ r l c r n m h } ; t ) t ァ r l n c n r n n m h } b ; c c c t イ t : e o s e e , ( h ; u イ t : t e t o s s e e , o ( o o o h ル s m t t a A ! r ` r ル e s e m t t t a A d ! n n n r の a s s i h d u r o フ n の a s n s n i h d u y r s s s o 内 s t T s r o e t e w ァ 内 s t t T t s b r o e t : e t o o w 容 y r o e e d r h s イ a 容 y r : o T e l e d r h s l l を n i k < s : s o p n ル w を n i k y < o s : s o b p e e e n 取 c n e s p : r o e の a 更 c n s e p v b p : r l o r . . e 得 g n t o " i n w 取 i 新 g t n e o o " i o n r e e w す f , : r n G { z s 得 t す f , r : : i = n P { z b s o r r る u i s E a e E に る u i d s U a , e r r r E n s n e T t . r 失 r n n s s > n e T t . T o o r c t g " i o r 敗 e c g t t e " i o e r r r t r > = , o k o し s t , r r { w = , o k x ( ( o i i n ) r ま p i i i n ) t " " r o n { a : ( し o o n n B a : 保 レ ( n g w { た n n g g l w { = 存 ス ` a ` 。 s , o a ` に ポ 保 f i B ス e u = b i B a 失 ン 存 e t e テ . p ( t e w 敗 ス に t a ー t d " [ a a し : 失 c f r タ e a a c f r i ま " 敗 h e e ス x t p o e e t し , し F t r コ t e p n t r た ま i c ー ( F l t c r 。 e し l h $ ド ) i i e h $ e ス r た e ( { : ; l c n ( { s テ r 。 C u a e a t u a p ー o ス o r c $ C t ] r c o タ r テ n l c { o i , l c n ス T ー t , e r n o , e s コ e タ e s e t n { s e ー x ス n { s s e / { s . ド t コ t T p n x t T t : ) ー ( o o t m y o e " ; ド k n ( l p k x , : e s " e e t n e : n ( r $ } . } ) e { ` s c ` ; s r , t o , p e a n o s t t n p u e s o s n e n } t . s ` T s e y t . p a s e t t u a } s t ) ) u ; ; s } ` ) ; 上記で使用するURLは以下です。 ...

2025年3月21日 · 15 分 · Nakamura

Next.js + CETEIcean + React TEI Routerを使ったビューア開発

概要 Next.js、CETEIcean、React TEI Routerを組み合わせたTEI/XMLビューアの開発についての備忘録です。 背景 CETEIceanは、TEI/XML を HTML5 に変換する JavaScript ライブラリです。 https://github.com/TEIC/CETEIcean そして、React TEI Routerは、CETEIcean をベースに React コンポーネントで TEI/XML を構造化して表示できるライブラリです。以下のように説明されています。 https://github.com/pfefferniels/react-teirouter TEI for React using CETEIcean and routes これらを組み合わせることで、Next.js において TEI/XML をカスタマイズして表示できるビューア を作成しました。 リポジトリ 以下がサンプルリポジトリです。 https://github.com/nakamura196/next-ceteicean-router 実際に動作するデモも用意しています。 https://next-ceteicean-router.vercel.app/ 実装 Next.js のページコンポーネント (page.tsx) CETEIcean を利用して XML を変換し、カスタムコンポーネントで描画します。 i i e } m m x p p p c r o o o o e r r r n < t t t t s T / u t E < T r R R d I t / E n e e e x e < t I a n f m x x b / e > < c d a l m t o < < b x ` R t e u C l > d d / d / o t ; e r l o n y i 私 d i < < d d > n f t n s > v の i v p p / i y d r f t = 名 v > p v > e o r f e " t 前 > s s > > r m o u n h y は t t m n t t p < y y x " c t e p l l m r " t = p = e e e l e @ i : " r = = C a / o ` / o s " " o c c n < / r N c c n t o ? w i a o o t " m A x w g m l l e ; p p m w i e o o n o p l . n r r t n ( t a c : : = e ) v e l o { n e i " r g g x t { r - > r r r m s s c e e e l / i . s e e C t o o p n n o e n r = ; ; n i = g " " " t " " / # > > e ; 1 n i こ こ n . s d ん ん t 0 / 1 に ば } " 1 " ち ん . > は は e 0 田 < > n " 中 / < ; c > 太 p s o 郎 > e d < g i / n p s g e t = r y " s l U N e T a = F m " - e c 8 > o " で l ? す o > 。 r : b l u e ; " > x x x < / s e g > TEIレンダリングコンポーネント CETEIcean を使って XML を HTML5 に変換。 TEIRender + TEIRoute を使い、TEI 要素ごとにカスタムコンポーネントを適用。 import { TEIRender, TEIRoute } from "react-teirouter";を使用した上で、要素毎にコンポーネントを用意しています。 ...

2025年3月2日 · 10 分 · Nakamura

Next.js for Drupal の BASE_PATH 問題と修正方法(patch-package活用)

概要 Next.js for Drupalのv2.0.0が2025/2/11にリリースされました。 https://next-drupal.org/ https://next-drupal.org/blog/next-drupal-2-0 早速試してみたところ、BASE_PATHの取り扱いについて対応が必要だったので、備忘録です。 環境変数 環境変数のサンプルは以下のようになっています。 # # N N # D D # D E E R R R S R X X A U U R U e e T T u P P e P e q _ _ t A A q A u P I h L L u L h i U M e _ _ i _ t r B A n C C r R t e L G t L L e E p d I E i I I d V s C _ c E E A : _ D a N N f L / D O t T T o I / R M i _ _ r D n U A o I S A e P I n D E O T x A N = C n E t L = R R - _ - _ s e E d S d B i t T e E r A t r = m C u S e i R a R p E . e e n E a _ e v t d T l U x e r = . R a i R R o L m t e e e r = p h v v t g h l i e a r / t e s l i d t . t i e o p c f h d v c s o r i a e s : m o s t / / m i t e / f o h n s / r n i v i a o s i t d m r e m f o . i / r n e n a o m x / d m e a c m n m o i / t p n n a - l f / d v e i c m a . g i r c n n i o s f / a m e i c b r g o l v / n e i s f s c e i e r g s / / i s c c e o e r n s v s / i u c c m o e e n s r s / u n m e e x r t この時、NEXT_PUBLIC_DRUPAL_BASE_URLにhttps://site.example.com/xxxのようなベースパスを含めた形で指定すると、APIのリクエストはhttps://site.example.com/jsonapi/などに送られ、リソースを正しく取得できませんでした。 ...

2025年3月2日 · 10 分 · Nakamura

Next.jsで多言語対応の静的サイトを構築する

はじめに この記事は、GPT-4oによって生成された内容です。Next.jsを使用して多言語対応の静的サイトを構築する方法について説明します。特に、メイン言語にはURLプレフィックスを付けず、その他の言語にはプレフィックスを付ける設定に焦点を当てます。GitHub Pagesを使用してデプロイする設定も含まれています。 プロジェクトのセットアップ まず、Next.jsのプロジェクトを作成します。create-next-appを使用してプロジェクトを初期化します。 n p x c r e a t e - n e x t - a p p @ l a t e s t n e x t - i n t l - s s g 必要なパッケージのインストール 多言語対応のために、next-intlをインストールします。 n p m i n s t a l l n e x t - i n t l プロジェクト構成 プロジェクトのディレクトリ構成は以下の通りです。 ...

2025年2月28日 · 6 分 · Nakamura

clover-iiifをNext.jsで使用する

概要 clover-iiifをNext.jsで使用するサンプルリポジトリを作成したので、備忘録です。 https://clover-iiif-demo.vercel.app/ 背景 clover-iiifは以下のように説明されています。 https://github.com/samvera-labs/clover-iiif Extensible IIIF front-end toolkit and Manifest viewer. Accessible. Composable. Open Source. (日本語訳)拡張可能な IIIF フロントエンドツールキットとマニフェストビューア。 これをNext.jsで使用します。 データ 「校異源氏物語(国立国会図書館所蔵)」をサンプルデータとして使用します。 https://dl.ndl.go.jp/pid/3437686 リポジトリ 以下で公開しています。 https://github.com/nakamura196/clover-iiif-demo 以下を参考にしました。 https://samvera-labs.github.io/clover-iiif/docs/composing クライアントサイドでの実行にあたり、以下のような工夫が必要でした。 " i i i c ) c } c } e u m m m o ; o ; o ; x s p p p n { n c c r ) n r ) p e o o o V s s o o e ; s e ; o r r r i t s t n n t < t t < r c t t t e = s s s u a / u S / t l w V > r W t t r r < a W r u < S i R d { e i : o n t V r o n s W u d e e y r e i r s m i i t r p o s e n a n u コ w m f k e a ( c e i k ( e r p f t c a s ン e p a C a n l w c n k e a " t m e ポ r o l o r i e e l = s C n u ; , i S ー r s n c f > r e e o s l c e ネ = t e t h e > n e t { a ン ( e P s i f t > f r ト d " } n a t i a e W S r c を y @ t r I i = l n o u o h 動 n s a d f > l t r s m P 的 a a = m C b k p a に m m s = o { a ; e " r イ i v n c n n a ン c e = s t k s e m ポ ( r e e = e x s ー a = u a n { t ト / > s r t < } / } ( c e c = d d S l { S h { i f y f S o e P m v r n r R v a a a > o a o を e r r n L m m m 無 r c a i o i 効 - h m f a " c " 化 i P s e d r " n ) i a . s i e ; e i r g t n a x f a e I g c t / m t d . t / v s ( } . " n i ( ' . ; a e ) m < v w ; a / i e n d g r i i a " f v t ) e > i , s } o t > n ' " ) ; " h t t p s : / / d l . n d l . g o . j p / a p i / i i i f / 3 4 3 7 6 8 6 / m a n i f e s t . j s o n " ; まとめ 不完全な点もあるかと思いますが、参考になりましたら幸いです。 ...

2025年2月17日 · 3 分 · Nakamura

NextAuth.jsを使ってDrupalのOAuthを利用する

概要 NextAuth.jsを使ってDrupalのOAuthを利用する方法に関する備忘録です。 挙動 Next.jsで作成したアプリにアクセスして、「Sign in」ボタンを押します。 Drupalにログインしていない場合には、ログイン画面に遷移します。 ログイン済みの場合、「許可」するかのボタンが表示されるので、許可します。 ログイン情報が表示されます。 Drupal側の準備 モジュールのインストール 以下のモジュールをインストールします。 https://www.drupal.org/project/simple_oauth 本記事執筆時点の最新の以下をインストールしました。 c o m p o s e r r e q u i r e ' d r u p a l / s i m p l e _ o a u t h : ^ 6 . 0 @ b e t a ' トークンを暗号化するための鍵の生成 鍵のペアを生成し、セキュリティのためにドキュメントルートの外に保存します。 ...

2025年1月9日 · 8 分 · Nakamura

Azure OpenAI Assistants APIを用いたアプリをGradioとNext.jsで作成する

概要 Azure OpenAI Assistants APIを用いたアプリをGradioとNext.jsで作成したので、備忘録です。 対象データ Zennで公開している記事を対象にしました。まず以下により、一括ダウンロードしました。 i f i f p u w f m r m r a r h o p o p o g l i r o m o m e s l r r e u r d a i f p u t i r s h t o w t b t t = = r e a r f o a r e f e o t x s i s q 1 l s t t r g l x s u m t . t r 4 o d 1 [ : p a i l e t o p p l m h e s m ] = o c e b a u i _ s c o = a f q i n = l n r r r + n o . o n = = k o . u m i f s e ( e t l = p p n s h e p w e p m " e r s a a i s t a a t e B s t d e r s o p h e r k c . 1 q t t i e o m i n i t r o t = s = t l a d h h n = a u l r ( t s t r t p i e p m . u u p . s t e t p r o d c p ( = e e r t . g ( e ( B s e n a l i e u x e i f e o x t e t : q s t e n n r f i q f i t s t x a q / u e a s d l " s u u n _ . _ t u d / e . [ ) a ( s d t e l d t p o ) t m z s j ' r " ) a s s S ( e a p i e t s a = t h : t ( t o c x t a f n s o r = i t a t s u l t h t u n . n t c t / e . p a ( . h l . g ( i 0 l p t x g ( s ) d , S d e ) c : e s e t e r s i o e t l s : x _ t e _ r " u v ( e : / t ( s = n w p / u s / p u p " a " a r ' z { a r o z m ) p l ] e u t l n n e i ) n r h ) s c ( a / n l ) e " t s a . . : . ) e r d s t x f t e p e t : i v l x _ c " i t o l t , p e + ( a s ' " t ? a / h h u r ' t ) s t ) m , e i [ l r c - . e n l 1 p x a e ] a i m [ } r s e ' . s t = p t e _ n a x r o a t t " k k h " ) = a ' T m ] r u ) u r e a ) 1 9 6 & p a g e = { p a g e } " ベクトルストアへの登録 以下のようなコードにより、データファイルをアップロードします。 ...

2025年1月6日 · 12 分 · Nakamura

openai-assistants-quickstartの微修正

概要 OpenAIのAssistants APIを用いたRAG( Retrieval-augmented generation)を用いたチャット画面の構築にあたり、以下のリポジトリを使用しました。 https://github.com/openai/openai-assistants-quickstart この時、citationの扱いについて修正が必要であったため、備忘録としてメモします。 背景 上記のリポジトリを使い、OpenAIのAssistants APIを用いたRAGを試みました。 この時、デフォルトの設定では、以下のように、「4:13†」のように、引用箇所を示す記号がそのまま表示されてしまいました。 対策 annotateLastMessageを以下のように修正しました。file_pathをfile_citationに変更することで、引用箇所を置換することができた。 一例として、以下では、File APIへのリンクに置換しています。 c o n } s ; t s } e ) a t c c } a } r ; n G M o o ; n ) e n e e n n n i } ; t o t s s s o f u t s t t . t u ) r a t a l a ( p ; n t h g l u a t a d a ` e e e a p s i n a n [ [ L s s d t o n t n リ . a c ( t a M n o e o ン . s u ( M t e s t d t ク . t r p e e s . a L a ] p M r r s d s f t a t ( r e e e s L a o i s i e s n v a a g r o t a v s t M g s e E n M n p M a e e t , a . e . i e g m s M c t s t / s e e s = e h y s e f s s a s ( p a x i a = s g p s ( e g t l g a e r a a e , e e ( g s e g n = . s s a e ) v e n = t / . n s M o = e $ s n = e = t x { l o > s a " t a i t s { t f n c a { a i i = n e t g o l o ( i e n e u t 0 o s ) _ p a , n [ c d t s p = i a i - ) r > t t o 1 e a e n ) = v { t d . , > M i L f e o a i u { s n s l p s " t e d a ) M _ a g e c t e { s i e s s t d . a a L l g t a e e i s n . o t g t n M t e . e h x f s t i s - . l a r e g 1 e _ e ] p i ] ; l d ; a } c ) e ` A l l ( 結果、以下のようにリンクが表示されました。 ...

2024年11月28日 · 3 分 · Nakamura

NextAuth.jsを使って、ORCID・The Open Science Framework・ GakuNin RDMの認証を行う

概要 NextAuth.jsを使って、ORCID・OSF(The Open Science Framework)・ GRDM(GakuNin RDM)の認証を行う方法です。 デモアプリ ORCID https://orcid-app.vercel.app/ OSF https://osf-app.vercel.app/ GRDM https://rdm-app.vercel.app/ リポジトリ ORCID https://github.com/nakamura196/orcid_app 以下がオプションの記述例です。 https://github.com/nakamura196/orcid_app/blob/main/src/app/api/auth/[…nextauth]/authOptions.js e } x ; p p ] c } o r , a , r o { } l a } a } t v , l s , s , i i n t c c a } t u } p } b y s s r y i } r c d d a y l l u , o s , r , a n e e e n f e o e : m p i i t u p } k e u a } o r } c c s s t c t t t n r e e e e h r a , e r r s , f e ; k s s u ( o o u s s " : : n n o l r s r r n i l y c } r i t i n e s s i i r j a k k r t : o t t r : a c e e : n : n o ) e l u d a m : e o o n w c e e n r " " I S i m o s d f c n h } ; t e r : m a s n n t c n n a [ c O o d e z " s p p i " o " s e , u ( n e i { s . . s ( o . . t u i R a : c a h : e o r h : h r t a A A r p p : l i a u e { u a o o t d C u r t t : n e t t e d u c n r { r : o c s s n c r k h " I t p e i t { s c t { t q r e t c o o p n c e s t t c c e O , D h r t o p " e t p p u e r h e a f f r p ( e r i o ) e i n p " " o : n s / _ _ s s e s s o p w i i o r { s . o k s d ; t , , c : : a t u : : s : r t a l l f o s i n e { s i e p / u y r / / t = i : i e e i f s T d ; n T = o s r { / t p i / / ( { z t ) [ l i e o , o n s o o h e : o p { a a " " e l s k = k a s . c r e : r u w t a r { o . e s e a e c e e c n p c b t a i p e r p . i n t c n c = n s i t " r i . o i o p s c e p o o c o v s d i c o d o k t n l . i r e n = k o = u { . . . c o c . r e : i j d s r , e u n O e o a d e o c n f c s - o s t n n a t R n r t e s r i s e ` a o i n o t o . t c . C v g e " s g d t B t n d ? n o k o c o I . / " , . / . } c e i ( e . ? k e r } o r D O o , e o o ) h a o ) n n . e n c ) u c _ R a n a r ( r n ; t a e n . i n i C C u v u g { ` e / i m m a d { t d L I t . t / h r j f e a } c ; . ; I D h N h v t s i ? i ) c a E _ / E / 3 t $ o e . l e c N C a X t . p { n r [ s { s c T L u T o 0 s t " " " ? s e _ I t A k / : o , ] g . T O s I E h U e [ / k . i e o R s D N o T n O / e p v m k C _ , T r H " R p n a e a e I t _ i _ , C u s t n i n D o S z U I b . h - l ; k E e R D . a , n ? I e C " L ] o c a . D n R , " r c m [ ; E + , c e e 0 を T i s s ] セ , " d s O " ? ッ / . _ R ] . シ a o t C ? e ョ p r o I . m ン i g k D v a に / / e a i 追 a v n の l l 加 u 3 } u , t . ` I e h 0 , D / / + c $ を a { 取 " l t 得 l o " b k a e + c n k s p / . r o o o r r f c c i i i l d d e " } . , ` p , e r { s o n ? . n a m e ? . [ " f a m i l y - n a m e " ] ? . v a l u e , OSF https://github.com/nakamura196/osf-app ...

2024年11月15日 · 21 分 · Nakamura

Knight LabのTimelineJSやStoryMapJSをNext.jsから利用する

概要 Knight LabのTimelineJSやStoryMapJSをNext.jsから利用する方法のメモです。 背景 Knight LabのTimelineJSやStoryMapJSは、デジタルストーリーテリングのためのオープンソースツールです。 https://knightlab.northwestern.edu/ データ 以下で公開されている『渋沢栄一伝記資料』のテキストデータを利用します。 https://github.com/shibusawa-dlab/lab1 リポジトリ 以下で公開しています。 https://github.com/nakamura196/shibusawa ストーリーマップ 以下のようなコンポーネントを用意することで、Next.jsからも利用することができました。 https://github.com/nakamura196/shibusawa/blob/main/src/components/Storymap.tsx TypeScriptの利用にあたり、以下の型定義ファイルも作成しました。 https://github.com/nakamura196/shibusawa/blob/main/src/global.d.ts 以下のように表示することができました。 https://shibusawa.vercel.app/storymap/1868-08-02 タイムライン ストーリーマップ同様、タイムラインについても以下のようなコンポーネントを作成しました。 https://github.com/nakamura196/shibusawa/blob/main/src/components/Timeline.tsx 以下のように表示することができました。 https://shibusawa.vercel.app/timeline/1868 ただし、タイムラインについては、以下でES6 modules/webpackが公開されていることに後から気がつきました。こちらの使い方について、別途調査したいと思います。 https://www.npmjs.com/package/@knight-lab/timelinejs まとめ デジタル・ヒューマニティーズ(DH)の分野で広く活用されているTimelineJSやStoryMapJSについて、データの視覚化や物語の構築を行う際の参考になりましたら幸いです。 なお、これらのツールはプログラムを介さず、Googleスプレッドシートを入力として、可視化アプリを作成することもできます。こちらも参考になりましたら幸いです。 https://timeline.knightlab.com/ https://storymap.knightlab.com/

2024年11月7日 · 1 分 · Nakamura

ZoteroのAPIをNext.jsから使う

概要 ZoteroのAPIをNext.jsから使う方法を調べましたので、備忘録です。結果、以下のアプリケーションを作成しました。 https://zotero-rouge.vercel.app/ ライブラリ 以下のライブラリを使用しました。 https://github.com/tnajdek/zotero-api-client API Keyなどの取得 以下の記事を参考にしてください。 使い方 コレクション一覧 i i i i i a ) } m m m m m s p p p p p y z z { c c r a o o o o o n o o o o e p r r r r r c t t n n t p t t t t t e e s s u / f r r t t r a { a { { { u o o n p p n A U m c i N i p d g c p s y o c / e r e e t i e a l o z x f i c t i K r p l l o t r s r S o e I i e l t R o m y e n y d c e e e m a p s : : = t c r s t s f i t o p " } i e s s a o i / o z } o t t t p n o c n o f n c r r i s n o s t r f h i i ( R s l e e o r } Z n n z e R l r m o o g g o s e e } o m f t , t p s c - " r e e o p t f a @ " o r r n o i r p / . m o o s n o o i l . C A e s n m - i / " o p e s c b . @ l i = . / " l . a l K r r n i p / u e e a a o e e r p t c y w w u x n i o h t ) a ; t t t s s 0 i . i e " m t / o l t . s ; a s n n i j e " / e s b m s r ; e x ( r y v n t a a e c j r p r r s y i " y - ( . ; p a " c t u u o i t s l o h e l n 0 r e " " " c ; ; , t i z o o n t s e ( r ) o . U g s e e t r ( I ) d ; ) ; 特定のコレクション i i i i i a ) } m m m m m s p p p p p y z z c { c c r a o o o o o n o o o o o e p r r r r r c t t l n n t p t t t t t e e l s s u / f r r e t t r a { a { { { u o o c n p p n A U t m c i N i p d g c p s i y o c / e r e e t i e o a l o z x f i c t i K r n p l l o t r s r S o e I I i e l t R o m y e n y d d c e e e m a p s : : : = t c r s t s f i t o p " } i e s s s a o i / o z } o t t t t p n o c n o f n c r r r i R n o s t r f h i i i ( e R l e e o r } Z n n n z s e l r m o o g g g o p s e } o m f t , , t o p c - " r e e n o t f a @ " o r r s n i r p / @ m o o e s o o i l / C A e n m - i a " o p = . / c b p @ l i r [ " l / p a l K a a i n i p / u e e w w d e e r a t c y a ; ] x n i p h t ) i / t t s i 0 i . t r " m / / o l s ; a p n n i m u e " o e ( b y t r ; s x r a e v t t a p . e s j r i t r / s y . s " e - ( c ; n a " o c u u l r t s l y h e e p 0 r c t " " t i ; , i o o n z n " o s ; t ( e c r o o l U l s e e c r t I i d o ) n ; I d ) . g e t ( ) ; 特定のコレクション内のアイテム一覧 i i i i i a ) m m m m m s p p p p p y z z c { c c r a o o o o o n o o o o o e p r r r r r c t t l n n . . . t p t t t t t e e l s s c i g u / f r r e t t o t e r a { a { { { u o o c l e t n p p n A U t m c l m ( i N i p d g c p s i y o e s ) c / e r e e t i e o a l c ( ; o z x f i c t i K r n p l t ) l o t r s r S o e I I i e i l t R o m y e n y d d c o e e e m a p s : : : = t n c r s t s f i s t o p " } i e s s s a o ( i / o z } o t t t t p n c o c n o f n c r r r i R o n o s t r f h i i i ( e l R l e e o r } Z n n n z s l e l , r m o o g g g o p e s e o m f t , , t o c p c N - " r e e n t o t e a @ " o r r s i n i x p / @ m o o e o s o t i l / C A n e n R - i a " o p = I . / e c b p @ l i d r [ q l / p a l K a ) a i u i p / u e e w w d e e r a t c y a ; ] s n i p h t ) i / t t s i 0 i . t i " m / / o l t } ; a p n n i m e " o e ( b y m f ; s x r a s r t t a p / o s j r i r m / s y o e - ( u " n a " t n c u u e e r t s . x y h e t t p 0 r s / t " " s i ; , e o r n z v " o e ; t r e " r ; o U s e r I d ) ; 参考 アプリケーションはVercelにホスティングされており、データベースにはVercel Postgres、ORMにはPrismaを使用しました。UIはTailwind CSSで構築され、ChatGPTのデザイン提案を使用しました。また、認証にはAuth0を採用しています。 ...

2024年11月1日 · 7 分 · Nakamura