diff --git a/README.md b/README.md
index 90fa633f..6a482a8c 100644
--- a/README.md
+++ b/README.md
@@ -46,10 +46,6 @@ use SilverStripe\LinkField\Form\LinkField;
 
 class Page extends SiteTree
 {
-    private static array $db = [
-        'DbLink' => DBLink::class
-    ];
-
     private static array $has_one = [
         'HasOneLink' => Link::class,
     ];
@@ -63,8 +59,8 @@ class Page extends SiteTree
             [
                 LinkField::create('HasOneLink'),
                 LinkField::create('DbLink'),
-            ]
-        )
+            ],
+        );
 
         return $fields;
     }
diff --git a/client/dist/js/bundle.js b/client/dist/js/bundle.js
index 74a7323d..4ca2af57 100644
--- a/client/dist/js/bundle.js
+++ b/client/dist/js/bundle.js
@@ -1 +1 @@
-!function(){"use strict";var e={274:function(e,t,n){var r=o(n(521)),i=o(n(154));function o(e){return e&&e.__esModule?e:{default:e}}document.addEventListener("DOMContentLoaded",(()=>{(0,r.default)(),(0,i.default)()}))},521:function(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var r=u(n(648)),i=u(n(809)),o=u(n(852)),a=u(n(117)),l=u(n(606));function u(e){return e&&e.__esModule?e:{default:e}}var d=()=>{r.default.component.registerMany({LinkPicker:i.default,LinkField:o.default,"LinkModal.FormBuilderModal":a.default,"LinkModal.InsertMediaModal":l.default})};t.default=d},154:function(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var r=o(n(648)),i=o(n(689));function o(e){return e&&e.__esModule?e:{default:e}}var a=()=>{r.default.query.register("readLinkTypes",i.default)};t.default=a},852:function(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var r=m(n(363)),i=n(827),o=n(624),a=n(648),l=p(n(42)),u=p(n(809)),d=m(n(123)),s=p(n(159)),f=p(n(510)),c=p(n(86));function p(e){return e&&e.__esModule?e:{default:e}}function y(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,n=new WeakMap;return(y=function(e){return e?n:t})(e)}function m(e,t){if(!t&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=y(t);if(n&&n.has(e))return n.get(e);var r={},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var o in e)if("default"!==o&&Object.prototype.hasOwnProperty.call(e,o)){var a=i?Object.getOwnPropertyDescriptor(e,o):null;a&&(a.get||a.set)?Object.defineProperty(r,o,a):r[o]=e[o]}return r.default=e,n&&n.set(e,r),r}const k="SilverStripe\\LinkField\\Controllers\\LinkFieldController",v=e=>{let{value:t,onChange:n,types:i,actions:o}=e;const l=t,[d,c]=(0,r.useState)(""),[p,y]=(0,r.useState)({}),[m,v]=(0,r.useState)(!1),_=p.Title||"",g=i.hasOwnProperty(d)?i[d]:{},h=d?i[d]:g,b=h&&h.hasOwnProperty("handlerName")?h.handlerName:"FormBuilderModal",O=(0,a.loadComponent)(`LinkModal.${b}`),M={title:_,description:p.description,typeTitle:g.title||"",onEdit:()=>{v(!0)},onClear:()=>{const e=`${f.default.getSection(k).form.linkForm.deleteUrl}/${l}`;s.default.delete(e,{},{"X-SecurityID":f.default.get("SecurityID")}).then((()=>{o.toasts.success("Deleted link")})).catch((()=>{o.toasts.error("Failed to delete link")})),c(""),y({}),n(0)},onSelect:e=>{c(e),v(!0)},types:Object.values(i)},j={typeTitle:g.title||"",typeKey:d,editing:m,onSubmit:async(e,t,r)=>{const i=await r();if(!i.id.match(/\/schema\/linkfield\/([0-9]+)/)){const e=i.id.match(/\/linkForm\/([0-9]+)/),t=parseInt(e[1],10);v(!1),n(t),o.toasts.success("Saved link")}return Promise.resolve()},onClosed:()=>{v(!1)},linkID:l};return(0,r.useEffect)((()=>{if(!m&&l){const e=`${f.default.getSection(k).form.linkForm.dataUrl}/${l}`;s.default.get(e).then((e=>e.json())).then((e=>{y(e),c(e.typeKey)}))}}),[m,l]),r.default.createElement(r.default.Fragment,null,r.default.createElement(u.default,M),r.default.createElement(O,j))};v.propTypes={value:c.default.number.isRequired,onChange:c.default.func.isRequired};var _=(0,i.compose)((0,a.injectGraphql)("readLinkTypes"),l.default,(0,o.connect)(null,(e=>({actions:{toasts:(0,i.bindActionCreators)(d,e)}}))))(v);t.default=_},606:function(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;d(n(754));var r=function(e,t){if(!t&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=u(t);if(n&&n.has(e))return n.get(e);var r={},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var o in e)if("default"!==o&&Object.prototype.hasOwnProperty.call(e,o)){var a=i?Object.getOwnPropertyDescriptor(e,o):null;a&&(a.get||a.set)?Object.defineProperty(r,o,a):r[o]=e[o]}r.default=e,n&&n.set(e,r);return r}(n(363)),i=d(n(475)),o=n(624),a=d(n(686)),l=d(n(86));function u(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,n=new WeakMap;return(u=function(e){return e?n:t})(e)}function d(e){return e&&e.__esModule?e:{default:e}}function s(){return s=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},s.apply(this,arguments)}const f=e=>{let{type:t,editing:n,data:o,actions:a,onSubmit:l,...u}=e;if(!t)return!1;(0,r.useEffect)((()=>{n?a.initModal():a.reset()}),[n]);const d=o?{ID:o.FileID,Description:o.Title,TargetBlank:!!o.OpenInNew}:{};return r.default.createElement(i.default,s({isOpen:n,type:"insert-link",title:!1,bodyClassName:"modal__dialog",className:"insert-link__dialog-wrapper--internal",fileAttributes:d,onInsert:e=>{let{ID:n,Description:r,TargetBlank:i}=e;return l({FileID:n,Title:r,OpenInNew:i,typeKey:t.key},"",(()=>{}))}},u))};f.propTypes={type:a.default.isRequired,editing:l.default.bool.isRequired,data:l.default.object.isRequired,actions:l.default.object.isRequired,onClick:l.default.func.isRequired};var c=(0,o.connect)((function(){return{}}),(function(e){return{actions:{initModal:()=>e({type:"INIT_FORM_SCHEMA_STACK",payload:{formSchema:{type:"insert-link",nextType:"admin"}}}),reset:()=>e({type:"RESET"})}}}))(f);t.default=c},117:function(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var r=d(n(363)),i=d(n(912)),o=d(n(872)),a=d(n(902)),l=d(n(510)),u=d(n(86));function d(e){return e&&e.__esModule?e:{default:e}}const s=(e,t)=>{const{schemaUrl:n}=l.default.getSection("SilverStripe\\LinkField\\Controllers\\LinkFieldController").form.linkForm,r=o.default.parse(n),i=a.default.parse(r.query);i.typeKey=e;for(const e of["href","path","pathname"])r[e]=`${r[e]}/${t}`;return o.default.format({...r,search:a.default.stringify(i)})},f=e=>{let{typeTitle:t,typeKey:n,linkID:o,editing:a,onSubmit:l,onClosed:u}=e;return!!n&&r.default.createElement(i.default,{title:t,isOpen:a,schemaUrl:s(n,o),identifier:"Link.EditingLinkInfo",onSubmit:l,onClosed:u})};f.propTypes={typeTitle:u.default.string.isRequired,typeKey:u.default.string.isRequired,linkID:u.default.number.isRequired,editing:u.default.bool.isRequired,onSubmit:u.default.func.isRequired,onClosed:u.default.func.isRequired};var c=f;t.default=c},809:function(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.default=t.Component=void 0;var r=u(n(363)),i=u(n(86)),o=u(n(820)),a=u(n(97)),l=u(n(734));function u(e){return e&&e.__esModule?e:{default:e}}const d=e=>{let{title:t,description:n,typeTitle:i,types:u,onSelect:d,onEdit:s,onClear:f}=e;return r.default.createElement("div",{className:(0,o.default)("link-picker","form-control",{"link-picker--selected":!!i})},!i&&r.default.createElement(a.default,{types:u,onSelect:d}),i&&r.default.createElement(l.default,{title:t,description:n,typeTitle:i,onClear:f,onClick:()=>s()}))};t.Component=d,d.propTypes={...a.default.propTypes,title:i.default.string,description:i.default.string,typeTitle:i.default.string.isRequired,onEdit:i.default.func.isRequired,onClear:i.default.func.isRequired,onSelect:i.default.func.isRequired};var s=d;t.default=s},97:function(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var r=d(n(754)),i=function(e,t){if(!t&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=u(t);if(n&&n.has(e))return n.get(e);var r={},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var o in e)if("default"!==o&&Object.prototype.hasOwnProperty.call(e,o)){var a=i?Object.getOwnPropertyDescriptor(e,o):null;a&&(a.get||a.set)?Object.defineProperty(r,o,a):r[o]=e[o]}r.default=e,n&&n.set(e,r);return r}(n(363)),o=d(n(86)),a=n(127),l=d(n(686));function u(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,n=new WeakMap;return(u=function(e){return e?n:t})(e)}function d(e){return e&&e.__esModule?e:{default:e}}const s=e=>{let{types:t,onSelect:n}=e;const[o,l]=(0,i.useState)(!1);return i.default.createElement(a.Dropdown,{isOpen:o,toggle:()=>l((e=>!e)),className:"link-picker__menu"},i.default.createElement(a.DropdownToggle,{className:"link-picker__menu-toggle font-icon-link",caret:!0},r.default._t("Link.ADD_LINK","Add Link")),i.default.createElement(a.DropdownMenu,null,t.map((e=>{let{key:t,title:r}=e;return i.default.createElement(a.DropdownItem,{key:t,onClick:()=>n(t)},r)}))))};s.propTypes={types:o.default.arrayOf(l.default).isRequired,onSelect:o.default.func.isRequired};var f=s;t.default=f},734:function(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var r=l(n(754)),i=l(n(363)),o=l(n(86)),a=n(127);function l(e){return e&&e.__esModule?e:{default:e}}const u=e=>t=>{t.nativeEvent.stopImmediatePropagation(),t.preventDefault(),t.nativeEvent.preventDefault(),t.stopPropagation(),e&&e()},d=e=>{let{title:t,description:n,typeTitle:o,onClear:l,onClick:d}=e;return i.default.createElement("div",{className:"link-picker__link"},i.default.createElement(a.Button,{className:"link-picker__button font-icon-link",color:"secondary",onClick:u(d)},i.default.createElement("div",{className:"link-picker__link-detail"},i.default.createElement("div",{className:"link-picker__title"},t),i.default.createElement("small",{className:"link-picker__type"},o,": ",i.default.createElement("span",{className:"link-picker__url"},n)))),i.default.createElement(a.Button,{className:"link-picker__clear",color:"link",onClick:u(l)},r.default._t("Link.CLEAR","Clear")))};d.propTypes={title:o.default.string,description:o.default.string,typeTitle:o.default.string.isRequired,onClear:o.default.func.isRequired,onClick:o.default.func.isRequired};var s=d;t.default=s},115:function(e,t,n){var r=l(n(311)),i=l(n(363)),o=l(n(691)),a=n(648);function l(e){return e&&e.__esModule?e:{default:e}}function u(){return u=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},u.apply(this,arguments)}r.default.entwine("ss",(e=>{e(".js-injector-boot .entwine-jsonfield").entwine({Component:null,Root:null,onmatch(){const e=this.closest(".cms-content").attr("id"),t=e?{context:e}:{},n=this.data("schema-component"),r=(0,a.loadComponent)(n,t);this.setComponent(r),this.setRoot(o.default.createRoot(this[0])),this._super(),this.refresh()},refresh(){const e=this.getProps(),t=this.getComponent();this.getRoot().render(i.default.createElement(t,u({},e,{noHolder:!0})))},handleChange(t){const n=e(this).data("field-id");e("#"+n).val(t),this.refresh()},getProps(){const t=e(this).data("field-id");return{value:Number(e("#"+t).val()),onChange:this.handleChange.bind(this)}},onunmatch(){this.getRoot().unmount()}})}))},689:function(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var r=n(648);const i={props(e){const{data:{error:t,readLinkTypes:n,loading:r}}=e,i=t&&t.graphQLErrors&&t.graphQLErrors.map((e=>e.message));return{loading:r,types:n?n.reduce(((e,t)=>({...e,[t.key]:t})),{}):{},graphQLErrors:i}}},{READ:o}=r.graphqlTemplates;var a={apolloConfig:i,templateName:o,pluralName:"LinkTypes",pagination:!1,params:{keys:"[ID]"},args:{root:{keys:"keys"}},fields:["key","title"]};t.default=a},686:function(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var r,i=(r=n(86))&&r.__esModule?r:{default:r};var o=i.default.shape({key:i.default.string.isRequired,title:i.default.string.isRequired});t.default=o},159:function(e){e.exports=Backend},510:function(e){e.exports=Config},42:function(e){e.exports=FieldHolder},912:function(e){e.exports=FormBuilderModal},648:function(e){e.exports=Injector},475:function(e){e.exports=InsertMediaModal},872:function(e){e.exports=NodeUrl},86:function(e){e.exports=PropTypes},363:function(e){e.exports=React},691:function(e){e.exports=ReactDomClient},624:function(e){e.exports=ReactRedux},127:function(e){e.exports=Reactstrap},827:function(e){e.exports=Redux},123:function(e){e.exports=ToastsActions},820:function(e){e.exports=classnames},754:function(e){e.exports=i18n},311:function(e){e.exports=jQuery},902:function(e){e.exports=qs}},t={};function n(r){var i=t[r];if(void 0!==i)return i.exports;var o=t[r]={exports:{}};return e[r](o,o.exports,n),o.exports}n(274),n(115)}();
\ No newline at end of file
+!function(){"use strict";var e={274:function(e,t,n){var r=o(n(521)),i=o(n(154));function o(e){return e&&e.__esModule?e:{default:e}}document.addEventListener("DOMContentLoaded",(()=>{(0,r.default)(),(0,i.default)()}))},521:function(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var r=u(n(648)),i=u(n(809)),o=u(n(852)),a=u(n(117)),l=u(n(606));function u(e){return e&&e.__esModule?e:{default:e}}var d=()=>{r.default.component.registerMany({LinkPicker:i.default,LinkField:o.default,"LinkModal.FormBuilderModal":a.default,"LinkModal.InsertMediaModal":l.default})};t.default=d},154:function(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var r=o(n(648)),i=o(n(689));function o(e){return e&&e.__esModule?e:{default:e}}var a=()=>{r.default.query.register("readLinkTypes",i.default)};t.default=a},852:function(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var r=m(n(363)),i=n(827),o=n(624),a=n(648),l=p(n(42)),u=p(n(809)),d=m(n(123)),s=p(n(159)),f=p(n(510)),c=p(n(86));function p(e){return e&&e.__esModule?e:{default:e}}function y(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,n=new WeakMap;return(y=function(e){return e?n:t})(e)}function m(e,t){if(!t&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=y(t);if(n&&n.has(e))return n.get(e);var r={},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var o in e)if("default"!==o&&Object.prototype.hasOwnProperty.call(e,o)){var a=i?Object.getOwnPropertyDescriptor(e,o):null;a&&(a.get||a.set)?Object.defineProperty(r,o,a):r[o]=e[o]}return r.default=e,n&&n.set(e,r),r}const k="SilverStripe\\LinkField\\Controllers\\LinkFieldController",v=e=>{let{value:t,onChange:n,types:i,actions:o}=e;const l=t,[d,c]=(0,r.useState)(""),[p,y]=(0,r.useState)({}),[m,v]=(0,r.useState)(!1),_=p.Title||"",g=i.hasOwnProperty(d)?i[d]:{},h=d?i[d]:g,b=h&&h.hasOwnProperty("handlerName")?h.handlerName:"FormBuilderModal",O=(0,a.loadComponent)(`LinkModal.${b}`),M={title:_,description:p.description,typeTitle:g.title||"",onEdit:()=>{v(!0)},onClear:()=>{const e=`${f.default.getSection(k).form.linkForm.deleteUrl}/${l}`;s.default.delete(e,{},{"X-SecurityID":f.default.get("SecurityID")}).then((()=>{o.toasts.success("Deleted link")})).catch((()=>{o.toasts.error("Failed to delete link")})),c(""),y({}),n(0)},onSelect:e=>{c(e),v(!0)},types:Object.values(i)},j={typeTitle:g.title||"",typeKey:d,editing:m,onSubmit:async(e,t,r)=>{const i=await r();if(!i.id.match(/\/schema\/linkfield\/([0-9]+)/)){const e=i.id.match(/\/linkForm\/([0-9]+)/),t=parseInt(e[1],10);v(!1),n(t),o.toasts.success("Saved link")}return Promise.resolve()},onClosed:()=>{v(!1)},linkID:l};return(0,r.useEffect)((()=>{if(!m&&l){const e=`${f.default.getSection(k).form.linkForm.dataUrl}/${l}`;s.default.get(e).then((e=>e.json())).then((e=>{y(e),c(e.typeKey)}))}}),[m,l]),r.default.createElement(r.default.Fragment,null,r.default.createElement(u.default,M),r.default.createElement(O,j))};v.propTypes={value:c.default.number.isRequired,onChange:c.default.func.isRequired};var _=(0,i.compose)((0,a.injectGraphql)("readLinkTypes"),l.default,(0,o.connect)(null,(e=>({actions:{toasts:(0,i.bindActionCreators)(d,e)}}))))(v);t.default=_},606:function(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;d(n(754));var r=function(e,t){if(!t&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=u(t);if(n&&n.has(e))return n.get(e);var r={},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var o in e)if("default"!==o&&Object.prototype.hasOwnProperty.call(e,o)){var a=i?Object.getOwnPropertyDescriptor(e,o):null;a&&(a.get||a.set)?Object.defineProperty(r,o,a):r[o]=e[o]}r.default=e,n&&n.set(e,r);return r}(n(363)),i=d(n(475)),o=n(624),a=d(n(686)),l=d(n(86));function u(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,n=new WeakMap;return(u=function(e){return e?n:t})(e)}function d(e){return e&&e.__esModule?e:{default:e}}function s(){return s=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},s.apply(this,arguments)}const f=e=>{let{type:t,editing:n,data:o,actions:a,onSubmit:l,...u}=e;if(!t)return!1;(0,r.useEffect)((()=>{n?a.initModal():a.reset()}),[n]);const d=o?{ID:o.FileID,Description:o.Title,TargetBlank:!!o.OpenInNew}:{};return r.default.createElement(i.default,s({isOpen:n,type:"insert-link",title:!1,bodyClassName:"modal__dialog",className:"insert-link__dialog-wrapper--internal",fileAttributes:d,onInsert:e=>{let{ID:n,Description:r,TargetBlank:i}=e;return l({FileID:n,Title:r,OpenInNew:i,typeKey:t.key},"",(()=>{}))}},u))};f.propTypes={type:a.default.isRequired,editing:l.default.bool.isRequired,data:l.default.object.isRequired,actions:l.default.object.isRequired,onClick:l.default.func.isRequired};var c=(0,o.connect)((function(){return{}}),(function(e){return{actions:{initModal:()=>e({type:"INIT_FORM_SCHEMA_STACK",payload:{formSchema:{type:"insert-link",nextType:"admin"}}}),reset:()=>e({type:"RESET"})}}}))(f);t.default=c},117:function(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var r=d(n(363)),i=d(n(912)),o=d(n(872)),a=d(n(902)),l=d(n(510)),u=d(n(86));function d(e){return e&&e.__esModule?e:{default:e}}const s=(e,t)=>{const{schemaUrl:n}=l.default.getSection("SilverStripe\\LinkField\\Controllers\\LinkFieldController").form.linkForm,r=o.default.parse(n),i=a.default.parse(r.query);i.typeKey=e;for(const e of["href","path","pathname"])r[e]=`${r[e]}/${t}`;return o.default.format({...r,search:a.default.stringify(i)})},f=e=>{let{typeTitle:t,typeKey:n,linkID:o,editing:a,onSubmit:l,onClosed:u}=e;return!!n&&r.default.createElement(i.default,{title:t,isOpen:a,schemaUrl:s(n,o),identifier:"Link.EditingLinkInfo",onSubmit:l,onClosed:u})};f.propTypes={typeTitle:u.default.string.isRequired,typeKey:u.default.string.isRequired,linkID:u.default.number.isRequired,editing:u.default.bool.isRequired,onSubmit:u.default.func.isRequired,onClosed:u.default.func.isRequired};var c=f;t.default=c},809:function(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.default=t.Component=void 0;var r=u(n(363)),i=u(n(86)),o=u(n(820)),a=u(n(97)),l=u(n(734));function u(e){return e&&e.__esModule?e:{default:e}}const d=e=>{let{title:t,description:n,typeTitle:i,types:u,onSelect:d,onEdit:s,onClear:f}=e;return r.default.createElement("div",{className:(0,o.default)("link-picker","form-control",{"link-picker--selected":!!i})},!i&&r.default.createElement(a.default,{types:u,onSelect:d}),i&&r.default.createElement(l.default,{title:t,description:n,typeTitle:i,onClear:f,onClick:()=>s()}))};t.Component=d,d.propTypes={...a.default.propTypes,title:i.default.string,description:i.default.string,typeTitle:i.default.string.isRequired,onEdit:i.default.func.isRequired,onClear:i.default.func.isRequired,onSelect:i.default.func.isRequired};var s=d;t.default=s},97:function(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var r=d(n(754)),i=function(e,t){if(!t&&e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var n=u(t);if(n&&n.has(e))return n.get(e);var r={},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var o in e)if("default"!==o&&Object.prototype.hasOwnProperty.call(e,o)){var a=i?Object.getOwnPropertyDescriptor(e,o):null;a&&(a.get||a.set)?Object.defineProperty(r,o,a):r[o]=e[o]}r.default=e,n&&n.set(e,r);return r}(n(363)),o=d(n(86)),a=n(127),l=d(n(686));function u(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,n=new WeakMap;return(u=function(e){return e?n:t})(e)}function d(e){return e&&e.__esModule?e:{default:e}}const s=e=>{let{types:t,onSelect:n}=e;const[o,l]=(0,i.useState)(!1);return i.default.createElement(a.Dropdown,{isOpen:o,toggle:()=>l((e=>!e)),className:"link-picker__menu"},i.default.createElement(a.DropdownToggle,{className:"link-picker__menu-toggle font-icon-link",caret:!0},r.default._t("Link.ADD_LINK","Add Link")),i.default.createElement(a.DropdownMenu,null,t.map((e=>{let{key:t,title:r}=e;return i.default.createElement(a.DropdownItem,{key:t,onClick:()=>n(t)},r)}))))};s.propTypes={types:o.default.arrayOf(l.default).isRequired,onSelect:o.default.func.isRequired};var f=s;t.default=f},734:function(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var r=l(n(754)),i=l(n(363)),o=l(n(86)),a=n(127);function l(e){return e&&e.__esModule?e:{default:e}}const u=e=>t=>{t.nativeEvent.stopImmediatePropagation(),t.preventDefault(),t.nativeEvent.preventDefault(),t.stopPropagation(),e&&e()},d=e=>{let{title:t,description:n,typeTitle:o,onClear:l,onClick:d}=e;return i.default.createElement("div",{className:"link-picker__link"},i.default.createElement(a.Button,{className:"link-picker__button font-icon-link",color:"secondary",onClick:u(d)},i.default.createElement("div",{className:"link-picker__link-detail"},i.default.createElement("div",{className:"link-picker__title"},t),i.default.createElement("small",{className:"link-picker__type"},o,": ",i.default.createElement("span",{className:"link-picker__url"},n)))),i.default.createElement(a.Button,{className:"link-picker__clear",color:"link",onClick:u(l)},r.default._t("Link.CLEAR","Clear")))};d.propTypes={title:o.default.string,description:o.default.string,typeTitle:o.default.string.isRequired,onClear:o.default.func.isRequired,onClick:o.default.func.isRequired};var s=d;t.default=s},41:function(e,t,n){var r=l(n(311)),i=l(n(363)),o=l(n(691)),a=n(648);function l(e){return e&&e.__esModule?e:{default:e}}function u(){return u=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},u.apply(this,arguments)}r.default.entwine("ss",(e=>{e(".js-injector-boot .entwine-linkfield").entwine({Component:null,Root:null,onmatch(){const e=this.closest(".cms-content").attr("id"),t=e?{context:e}:{},n=this.data("schema-component"),r=(0,a.loadComponent)(n,t);this.setComponent(r),this.setRoot(o.default.createRoot(this[0])),this._super(),this.refresh()},refresh(){const e=this.getProps(),t=this.getComponent();this.getRoot().render(i.default.createElement(t,u({},e,{noHolder:!0})))},handleChange(t){const n=e(this).data("field-id");e("#"+n).val(t),this.refresh()},getProps(){const t=e(this).data("field-id");return{value:Number(e("#"+t).val()),onChange:this.handleChange.bind(this)}},onunmatch(){this.getRoot().unmount()}})}))},689:function(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var r=n(648);const i={props(e){const{data:{error:t,readLinkTypes:n,loading:r}}=e,i=t&&t.graphQLErrors&&t.graphQLErrors.map((e=>e.message));return{loading:r,types:n?n.reduce(((e,t)=>({...e,[t.key]:t})),{}):{},graphQLErrors:i}}},{READ:o}=r.graphqlTemplates;var a={apolloConfig:i,templateName:o,pluralName:"LinkTypes",pagination:!1,params:{keys:"[ID]"},args:{root:{keys:"keys"}},fields:["key","title"]};t.default=a},686:function(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var r,i=(r=n(86))&&r.__esModule?r:{default:r};var o=i.default.shape({key:i.default.string.isRequired,title:i.default.string.isRequired});t.default=o},159:function(e){e.exports=Backend},510:function(e){e.exports=Config},42:function(e){e.exports=FieldHolder},912:function(e){e.exports=FormBuilderModal},648:function(e){e.exports=Injector},475:function(e){e.exports=InsertMediaModal},872:function(e){e.exports=NodeUrl},86:function(e){e.exports=PropTypes},363:function(e){e.exports=React},691:function(e){e.exports=ReactDomClient},624:function(e){e.exports=ReactRedux},127:function(e){e.exports=Reactstrap},827:function(e){e.exports=Redux},123:function(e){e.exports=ToastsActions},820:function(e){e.exports=classnames},754:function(e){e.exports=i18n},311:function(e){e.exports=jQuery},902:function(e){e.exports=qs}},t={};function n(r){var i=t[r];if(void 0!==i)return i.exports;var o=t[r]={exports:{}};return e[r](o,o.exports,n),o.exports}n(274),n(41)}();
\ No newline at end of file
diff --git a/client/src/bundles/bundle.js b/client/src/bundles/bundle.js
index 3a3c1409..7622ced6 100644
--- a/client/src/bundles/bundle.js
+++ b/client/src/bundles/bundle.js
@@ -6,4 +6,4 @@
 // require('expose-loader?InsertMediaModal!containers/InsertMediaModal/InsertMediaModal');
 
 import 'boot';
-import 'entwine/JsonField';
+import 'entwine/LinkField';
diff --git a/client/src/entwine/JsonField.js b/client/src/entwine/LinkField.js
similarity index 96%
rename from client/src/entwine/JsonField.js
rename to client/src/entwine/LinkField.js
index c89ffd65..ad7a472f 100644
--- a/client/src/entwine/JsonField.js
+++ b/client/src/entwine/LinkField.js
@@ -6,7 +6,7 @@ import ReactDOM from 'react-dom/client';
 import { loadComponent } from 'lib/Injector';
 
 jQuery.entwine('ss', ($) => {
-  $('.js-injector-boot .entwine-jsonfield').entwine({
+  $('.js-injector-boot .entwine-linkfield').entwine({
 
     Component: null,
     Root: null,
diff --git a/src/Form/JsonField.php b/src/Form/JsonField.php
deleted file mode 100644
index f53d1444..00000000
--- a/src/Form/JsonField.php
+++ /dev/null
@@ -1,49 +0,0 @@
-<?php declare(strict_types=1);
-
-namespace SilverStripe\LinkField\Form;
-
-use InvalidArgumentException;
-use SilverStripe\Forms\FormField;
-use SilverStripe\ORM\DataObject;
-use SilverStripe\ORM\DataObjectInterface;
-use SilverStripe\LinkField\Models\Link;
-
-/**
- * Field designed to edit complex data passed as a JSON string. Other FormFields can be built on top of this one.
- *
- * It will output a hidden input with serialize JSON Data.
- */
-abstract class JsonField extends FormField
-{
-    protected $schemaDataType = FormField::SCHEMA_DATA_TYPE_CUSTOM;
-    protected $inputType = 'hidden';
-
-    public function setValue($value, $data = null)
-    {
-        if (is_a($value, Link::class)) {
-            $id = $value->ID;
-        } else {
-            $id = $value;
-        }
-        return parent::setValue($id, $data);
-    }
-
-    /**
-     * @param DataObject|DataObjectInterface $record - A DataObject such as a Page
-     * @return $this
-     */
-    public function saveInto(DataObjectInterface $record)
-    {
-        // Check required relation details are available
-        $fieldname = $this->getName();
-        if (!$fieldname) {
-            return $this;
-        }
-
-        $linkID = $this->dataValue();
-        $dbColumn = $fieldname . 'ID';
-        $record->$dbColumn = $linkID;
-
-        return $this;
-    }
-}
diff --git a/src/Form/LinkField.php b/src/Form/LinkField.php
index 7f5c1a1e..d7aeb980 100644
--- a/src/Form/LinkField.php
+++ b/src/Form/LinkField.php
@@ -2,10 +2,47 @@
 
 namespace SilverStripe\LinkField\Form;
 
+use SilverStripe\Forms\FormField;
+use SilverStripe\ORM\DataObject;
+use SilverStripe\ORM\DataObjectInterface;
+use SilverStripe\LinkField\Models\Link;
+
 /**
  * Allows CMS users to edit a Link object.
  */
-class LinkField extends JsonField
+class LinkField extends FormField
 {
     protected $schemaComponent = 'LinkField';
+
+    protected $schemaDataType = FormField::SCHEMA_DATA_TYPE_CUSTOM;
+    protected $inputType = 'hidden';
+
+    public function setValue($value, $data = null)
+    {
+        if (is_a($value, Link::class)) {
+            $id = $value->ID;
+        } else {
+            $id = $value;
+        }
+        return parent::setValue($id, $data);
+    }
+
+    /**
+     * @param DataObject|DataObjectInterface $record - A DataObject such as a Page
+     * @return $this
+     */
+    public function saveInto(DataObjectInterface $record)
+    {
+        // Check required relation details are available
+        $fieldname = $this->getName();
+        if (!$fieldname) {
+            return $this;
+        }
+
+        $linkID = $this->dataValue();
+        $dbColumn = $fieldname . 'ID';
+        $record->$dbColumn = $linkID;
+
+        return $this;
+    }
 }
diff --git a/src/JsonData.php b/src/JsonData.php
deleted file mode 100644
index 89ba7201..00000000
--- a/src/JsonData.php
+++ /dev/null
@@ -1,17 +0,0 @@
-<?php declare(strict_types=1);
-
-namespace SilverStripe\LinkField;
-
-use JsonSerializable;
-
-/**
- * An object that can be serialized and deserialized to JSON.
- */
-interface JsonData extends JsonSerializable
-{
-    /**
-     * @param array|JsonData $data
-     * @return $this
-     */
-    public function setData($data): self;
-}
diff --git a/src/Models/Link.php b/src/Models/Link.php
index e57f3217..6657da9c 100644
--- a/src/Models/Link.php
+++ b/src/Models/Link.php
@@ -10,7 +10,6 @@
 use SilverStripe\Forms\DropdownField;
 use SilverStripe\Forms\FieldList;
 use SilverStripe\Forms\RequiredFields;
-use SilverStripe\LinkField\JsonData;
 use SilverStripe\LinkField\Type\Registry;
 use SilverStripe\ORM\DataObject;
 use SilverStripe\ORM\FieldType\DBHTMLText;
@@ -22,7 +21,7 @@
  * @property string $Title
  * @property bool $OpenInNew
  */
-class Link extends DataObject implements JsonData
+class Link extends DataObject
 {
     private static $table_name = 'LinkField_Link';
 
@@ -124,7 +123,7 @@ public function onBeforeWrite(): void
         parent::onBeforeWrite();
     }
 
-    function setData($data): JsonData
+    function setData($data): Link
     {
         if (is_string($data)) {
             $data = json_decode($data, true);
@@ -136,7 +135,7 @@ function setData($data): JsonData
                     json_last_error_msg()
                 ));
             }
-        } elseif ($data instanceof JsonData) {
+        } elseif ($data instanceof Link) {
             $data = $data->jsonSerialize();
         }
 
@@ -193,7 +192,7 @@ public function jsonSerialize(): mixed
         return $data;
     }
 
-    public function loadLinkData(array $data): JsonData
+    public function loadLinkData(array $data): Link
     {
         $link = new static();
 
diff --git a/templates/SilverStripe/LinkField/Form/JsonField.ss b/templates/SilverStripe/LinkField/Form/LinkField.ss
similarity index 72%
rename from templates/SilverStripe/LinkField/Form/JsonField.ss
rename to templates/SilverStripe/LinkField/Form/LinkField.ss
index e11bdc72..c63fb16a 100644
--- a/templates/SilverStripe/LinkField/Form/JsonField.ss
+++ b/templates/SilverStripe/LinkField/Form/LinkField.ss
@@ -1,2 +1,2 @@
 <input $AttributesHTML />
-<div data-field-id="$ID" data-schema-component="$SchemaComponent" class="entwine-jsonfield"></div>
+<div data-field-id="$ID" data-schema-component="$SchemaComponent" class="entwine-linkfield"></div>