[{"data":1,"prerenderedAt":2551},["ShallowReactive",2],{"homepage-latest-articles":3,"$fqW3EdRqgvOJB-ZwqQ4lGznftWr2io_0xGC6bQ4JoovM":443,"$fl6nV3FmOja_AYx44xMfI526LW7UIyIr3O6Fkn4_J1pU":506,"$fZVPMCR-2wArN9zrFaM7QwDz2gT_N-GDSsD_wOCG0h1k":597,"$fDBJ9Rlba5SD068T0Y_1TIhxYQrGqN1hMRMyDnphUiVQ":749,"$f5aXNBbisywp_RmkrClCGiVNf8Zry7ElRYLBuaZnlnd0":901,"$fdadetfquWbG4gPI2u9XP8NbWqI2O4-Y0Cx6Hxvx_Ds4":1201},[4,132,238,347],{"id":5,"title":6,"articleType":7,"categories":8,"date":11,"description":12,"extension":13,"meta":14,"paragraphs":15,"path":127,"readingTime":128,"sitemap":129,"stem":130,"__hash__":131},"articleEntries\u002Farticles-data\u002Ffile-field-paths-8x-10-stable-and-back-under-maintenance-20261001.json","File (Field) Paths 8.x-1.0; stable and back under maintenance","Blog post",[9,10],"Drupal","Planet Drupal","2026-10-01T16:00:00+10:00","Drupal drops your uploads in a dated folder and leaves the filename alone. File (Field) Paths builds both from tokens instead. 8.x-1.0 is stable on Drupal 10.3 and 11, and the module is actively maintained again.","json",{},[16,26,50,58,81,93,103,113,122],{"type":17,"layout":18,"regions":19},"section","layout_onecol",{"content":20},[21,24],{"type":22,"html":23},"text_formatted","\u003Cp>File (Field) Paths is stable. \u003Ccode>8.x-1.0\u003C\u002Fcode> is the first stable release since the Drupal 7 one (long may it live), and it does what it has always done: sorts and renames your uploads with token patterns, so you get a filesystem you can read.\u003C\u002Fp>",{"type":22,"html":25},"\u003Cp>If you've been holding off while it sat in RC, you don't need to. It has 215 automated tests and 1287 assertions where \u003Ccode>beta8\u003C\u002Fcode> had 21 tests, a safer default for where uploads wait, and a plan for what comes next. It's under active maintenance again.\u003C\u002Fp>",{"type":17,"title":27,"layout":18,"regions":28},"If you haven't used it",{"content":29},[30,32,34,39,41,43],{"type":22,"html":31},"\u003Cp>Core file fields let you choose a directory, and that setting takes tokens. Drupal ships \u003Ccode>[date:custom:Y]-[date:custom:m]\u003C\u002Fcode> as the default. What it can't take is a token about the entity you're attaching the file to, because at the moment the file is saved those values don't exist yet. The file name isn't touched at all.\u003C\u002Fp>",{"type":22,"html":33},"\u003Cp>It puts the upload somewhere else first, waits for the save, then moves and renames it once the tokens mean something. You get two patterns per field. Here's what I run on an article's image field:\u003C\u002Fp>",{"type":35,"title":36,"code":37,"language":38},"code","The settings on an article's image field","File path    [node:url:path]\nFile name    [file:ffp-name-only-original].[file:ffp-extension-original]","text",{"type":22,"html":40},"\u003Cp>Upload \u003Ccode>FFP Showcase Hero Shot.PNG\u003C\u002Fcode> to this post and it ends up at \u003Ccode>writing\u002Ffile-field-paths-8x-10-stable-and-back-under-maintenance-20261001\u002Fffp-showcase-hero-shot.png\u003C\u002Fcode>. The directory is the post's own URL, the name gets transliterated and cleaned up on the way through, and the original filename stays on the file record. You'll want Pathauto installed for the cleaning, and \u003Cem>Cleanup using Pathauto\u003C\u002Fem> ticked on the file name, or the raw value goes straight in. Building the path out of the entity the file belongs to is the part core has never done.\u003C\u002Fp>",{"type":22,"html":42},"\u003Cp>Changing a pattern doesn't touch anything you've already uploaded. New files follow it, old ones stay put until you ask, either with \u003Cem>Retroactive update\u003C\u002Fem> on the field or \u003Ccode>drush filefield_paths:update\u003C\u002Fcode>. Do that on a copy first. It moves every file at once, and it'll break links to them unless \u003Cem>Create Redirect\u003C\u002Fem> is on, which wants the \u003Ca href=\"https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Fredirect\">Redirect\u003C\u002Fa> module.\u003C\u002Fp>",{"type":44,"alt":45,"caption":46,"width":47,"height":48,"src":49},"media","The File (Field) Paths section of an image field's settings form, showing a file path and file name built from node tokens","\u003Cp>A path and a name built from the entity the file is attached to. That is the whole trick.\u003C\u002Fp>",960,1040,"\u002Fimages\u002Fwriting\u002Ffile-field-paths-8x-10-stable-and-back-under-maintenance-20261001\u002Ffilefield-paths-10-field-settings.png",{"type":17,"title":51,"layout":18,"regions":52},"What's new in 8.x-1.0",{"content":53},[54,56],{"type":22,"html":55},"\u003Cp>The image widget no longer shows the wrong thumbnail when two uploads share a name (\u003Ca href=\"https:\u002F\u002Fwww.drupal.org\u002Fi\u002F3277844\">#3277844\u003C\u002Fa>). A new upload no longer creates a redirect every time (\u003Ca href=\"https:\u002F\u002Fwww.drupal.org\u002Fi\u002F3494240\">#3494240\u003C\u002Fa>), and the PHP 8.2 that \u003Ccode>rc2\u003C\u002Fcode> already needed is finally declared (\u003Ca href=\"https:\u002F\u002Fwww.drupal.org\u002Fi\u002F3622262\">#3622262\u003C\u002Fa>). Being stable also means security advisory coverage.\u003C\u002Fp>",{"type":22,"html":57},"\u003Cp>I've been putting all of my modules on \u003Ca href=\"https:\u002F\u002Fwww.drupal.org\u002Fu\u002Falexskrypnyk\">Alex Skrypnyk\u003C\u002Fa>'s \u003Ca href=\"https:\u002F\u002Fgithub.com\u002FAlexSkrypnyk\u002Fdrupal_extension_scaffold\">Drupal Extension Scaffold\u003C\u002Fa>, running Drupal's own CI templates on my own GitLab with GitHub beside it. Most of my time on this release went into the tests that pipeline runs: 9 test files at \u003Ccode>rc1\u003C\u002Fcode>, 36 now. That's what tells me the module still works when I come back to it after months on something else.\u003C\u002Fp>",{"type":17,"title":59,"layout":18,"regions":60},"Where uploads wait",{"content":61},[62,64,67,69,73,75],{"type":22,"html":63},"\u003Cp>Because the tokens only resolve once the entity is saved, every upload waits somewhere first. If that staging directory sits under \u003Ccode>public:\u002F\u002F\u003C\u002Fcode>, a file headed for a private field is in the web root until the save finishes. The module's been saying so on the status report since \u003Ccode>beta6\u003C\u002Fcode> in December 2022, as a partial fix for \u003Ca href=\"https:\u002F\u002Fwww.drupal.org\u002Fsa-contrib-2022-065\">SA-CONTRIB-2022-065\u003C\u002Fa>:\u003C\u002Fp>",{"type":35,"title":65,"code":66,"language":38},"The status report, when staging points at public:\u002F\u002F","File (Field) Paths temporary path      Insecure!\n\nThis site supports private files but the File (Field) Paths temporary\npath is under public:\u002F\u002F which could lead to private files being\ntemporarily exposed publicly. Change the temporary path to be under\ntemporary:\u002F\u002F or private:\u002F\u002F in order to secure your files.",{"type":22,"html":68},"\u003Cp>That release also added an update hook, so database updates move a \u003Ccode>public:\u002F\u002F\u003C\u002Fcode> staging path onto \u003Ccode>temporary:\u002F\u002F\u003C\u002Fcode>, or \u003Ccode>private:\u002F\u002F\u003C\u002Fcode> if \u003Ccode>temporary:\u002F\u002F\u003C\u002Fcode> isn't writable. If you've run updates any time since 2022 it's already happened:\u003C\u002Fp>",{"type":35,"title":70,"code":71,"language":72,"highlighted":71},"Check where uploads wait","drush config:get filefield_paths.settings temp_location","bash",{"type":22,"html":74},"\u003Cp>Since \u003Ccode>rc1\u003C\u002Fcode> a field can set its own staging location, and the update hook and the status report don't check that override yet. If you've set one, have a look at it. It's on the \u003Ccode>1.1\u003C\u002Fcode> list. \u003Ccode>temporary:\u002F\u002F\u003C\u002Fcode> has been the recommended scheme since 2022, and now that \u003Ca href=\"https:\u002F\u002Fwww.drupal.org\u002Fi\u002F3121826\">#3121826\u003C\u002Fa> in \u003Ccode>rc2\u003C\u002Fcode> builds image derivatives on demand, \u003Ccode>private:\u002F\u002F\u003C\u002Fcode> is only for the case it was always for: several web servers with no shared temporary directory.\u003C\u002Fp>",{"type":44,"alt":76,"caption":77,"width":78,"height":79,"src":80},"The File (Field) Paths settings form with Temporary file location set to temporary:\u002F\u002Ffilefield_paths","\u003Cp>The site-wide setting, at Configuration &gt; Media &gt; File system &gt; File (Field) Paths.\u003C\u002Fp>",984,296,"\u002Fimages\u002Fwriting\u002Ffile-field-paths-8x-10-stable-and-back-under-maintenance-20261001\u002Ffilefield-paths-10-temporary-location.png",{"type":17,"title":82,"layout":18,"regions":83},"What's next",{"content":84},[85,87,89,91],{"type":22,"html":86},"\u003Cp>Field Tokens, Custom Formatters and JSON:API Views have each had this treatment this year. This is the fourth, and the one with the longest queue. The code is modern and the tests are in. The queue is next.\u003C\u002Fp>",{"type":22,"html":88},"\u003Cp>The \u003Ca href=\"https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Ffilefield_paths\u002F-\u002Fmilestones\">milestones\u003C\u002Fa> carry that plan. \u003Ccode>1.0\u003C\u002Fcode> takes bug fixes only, \u003Ccode>1.1\u003C\u002Fcode> is where the queue catch-up goes, \u003Ccode>1.2\u003C\u002Fcode> is the long tail, and breaking changes wait for \u003Ccode>2.0.0\u003C\u002Fcode>. The oldest open issue, \u003Ca href=\"https:\u002F\u002Fwww.drupal.org\u002Fi\u002F1115740\">#1115740\u003C\u002Fa> from April 2011, is on the \u003Ccode>1.1\u003C\u002Fcode> list, with a kernel test on its issue fork that reproduces it. The patch is still to write.\u003C\u002Fp>",{"type":22,"html":90},"\u003Cp>If you want to take something on, \u003Ca href=\"https:\u002F\u002Fwww.drupal.org\u002Fi\u002F3069511\">#3069511\u003C\u002Fa>, replacing existing files, is the most-watched issue in the queue and needs a design decision more than it needs code. \u003Ca href=\"https:\u002F\u002Fwww.drupal.org\u002Fi\u002F3182718\">#3182718\u003C\u002Fa>, taxonomy hierarchy in paths, has a community patch waiting on review.\u003C\u002Fp>",{"type":22,"html":92},"\u003Cp>If you write code against this one, I've deprecated six procedural functions in \u003Ccode>8.x-1.0\u003C\u002Fcode> and they go in \u003Ccode>2.0.0\u003C\u002Fcode>. Each has a \u003Ccode>#[\\Deprecated]\u003C\u002Fcode> attribute naming what replaced it, so Upgrade Status will tell you if you're calling them.\u003C\u002Fp>",{"type":17,"title":94,"layout":18,"regions":95},"A big thanks to the community",{"content":96},[97,99,101],{"type":22,"html":98},"\u003Cp>Big thanks to \u003Ca href=\"https:\u002F\u002Fwww.drupal.org\u002Fu\u002Fvoleger\">Oleh Vehera\u003C\u002Fa>, who kept this module alive while my focus was elsewhere. The Drupal 9 port, then Drupal 10, the move to Drush 12, the hooks lifted into classes and the services behind them are all his. So is the status report warning above. He has commit access.\u003C\u002Fp>",{"type":22,"html":100},"\u003Cp>And to everyone else who kept it moving. rpayanm, dunebaud and Paulino Michelazzo cut releases. Bryan Sharpe, Peter Wolanin, Jeremy Stoller, Chandansha Fakir, Youri van Koppen and solideogloria got \u003Ccode>rc1\u003C\u002Fcode> out. dshields, xamount, Sakshi Sharma and Francesco Maria Battaglia fixed the last things standing between \u003Ccode>rc2\u003C\u002Fcode> and today. Jeffrey Clark, Aidan Lister and Magnus Gunnarsson were doing this back in the Drupal 6 days. If you have ever put a patch on this module, your name is in the changelog.\u003C\u002Fp>",{"type":22,"html":102},"\u003Cp>I'm independent now, working on open source full time, across Drupal and Druxt. There's no client work paying for it, so sponsorship is what makes the time possible. That's what got \u003Ccode>8.x-1.0\u003C\u002Fcode> out, and it's what keeps the rest of them moving.\u003C\u002Fp>",{"type":17,"layout":18,"regions":104},{"content":105},[106,108,111],{"type":22,"html":107},"\u003Cp>Tens of thousands of sites run this one, and several thousand are still on \u003Ccode>7.x-1.x\u003C\u002Fcode>. If any of this is useful to you, \u003Ccode>8.x-1.0\u003C\u002Fcode> is out now:\u003C\u002Fp>",{"type":35,"code":109,"language":72,"highlighted":110},"composer require 'drupal\u002Ffilefield_paths:^1.0'","\u003Cspan class=\"token function\">composer\u003C\u002Fspan> require \u003Cspan class=\"token string\">'drupal\u002Ffilefield_paths:^1.0'\u003C\u002Fspan>",{"type":22,"html":112},"\u003Cp>Composer maps the tag to \u003Ccode>1.0.0\u003C\u002Fcode>, so \u003Ccode>^1.0\u003C\u002Fcode> is the constraint you want. If you're stuck on PHP 8.1, \u003Ccode>1.0.0-rc1\u003C\u002Fcode> is the last release that runs there, but it carries bugs \u003Ccode>rc2\u003C\u002Fcode> fixed and the security team doesn't cover release candidates. Moving to 8.2 is the better answer.\u003C\u002Fp>",{"type":17,"layout":18,"regions":114},{"content":115},[116],{"type":117,"description":118,"url":119,"gitpod":120,"drupalUrl":121},"repository","\u003Cp>Source on GitHub, with the project page, the issue queue and the full changelog on Drupal.org. Patches welcome in the queue, and if your sites lean on this one, sponsoring is what keeps it maintained.\u003C\u002Fp>","https:\u002F\u002Fgithub.com\u002FDecipher\u002Ffilefield_paths",false,"https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Ffilefield_paths",{"type":17,"layout":18,"regions":123},{"content":124},[125],{"type":22,"html":126},"\u003Cp>So what's in your path pattern? Mine is the post's own URL. I'd like to know what people are doing with the entity tokens I never thought to try.\u003C\u002Fp>","\u002Fwriting\u002Ffile-field-paths-8x-10-stable-and-back-under-maintenance-20261001","5 min",{"loc":127},"articles-data\u002Ffile-field-paths-8x-10-stable-and-back-under-maintenance-20261001","lBJkLMpRX7c3Mt2j7IQM2KIGkSbEDbAJ8htkFdy0rrs",{"id":133,"title":134,"articleType":7,"categories":135,"date":137,"description":138,"extension":13,"meta":139,"paragraphs":140,"path":233,"readingTime":234,"sitemap":235,"stem":236,"__hash__":237},"articleEntries\u002Farticles-data\u002Fdruxt-auth-050-two-ways-to-sign-in-20260926.json","Druxt Auth 0.5.0; two ways to sign in without leaving your site",[9,136,10],"Druxt","2026-09-26T21:30:00+10:00","Simple OAuth 6 removed the password grant. Druxt Auth 0.5.0 gets it working again through a contrib module, and the authorization code grant now takes credentials too, so a Nuxt frontend signs people in without sending them to Drupal.",{},[141,154,177,193,209,227],{"type":17,"layout":18,"regions":142},{"content":143},[144,146,148],{"type":22,"html":145},"\u003Cp>Every Druxt site I have built signs people in by sending them somewhere else to do it: out to Drupal's login page, on to a consent screen, and eventually back. With Druxt Auth \u003Ccode>0.5.0\u003C\u002Fcode> the username and password can now be handled entirely in the frontend instead, either through the authorization code grant or through the password grant.\u003C\u002Fp>",{"type":22,"html":147},"\u003Cp>If you have not used it, Druxt Auth wires Nuxt's auth module to \u003Ca href=\"https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Fsimple_oauth\">Simple OAuth\u003C\u002Fa> on the Drupal side. It targets Nuxt 2 today, because \u003Ccode>@nuxtjs\u002Fauth-next\u003C\u002Fcode> does.\u003C\u002Fp>",{"type":44,"alt":149,"caption":150,"width":151,"height":152,"src":153},"The druxtjs.org playground rendering an Umami recipe block, with a Sign in to edit dialog open over it","\u003Cp>Signing in happens on the page you were already on.\u003C\u002Fp>",2560,1440,"\u002Fimages\u002Fwriting\u002Fdruxt-auth-050-two-ways-to-sign-in-20260926\u002Fdruxt-auth-sign-in-dialog.png",{"type":17,"title":155,"layout":18,"regions":156},"The two ways in",{"content":157},[158,160,165,167,169,173,175],{"type":22,"html":159},"\u003Cp>The first is the \u003Cstrong>authorization code grant\u003C\u002Fstrong>, which now takes credentials directly. Druxt Auth signs the visitor in through Drupal's JSON login route first, so the authorize step finds a session waiting and returns a code without rendering anything:\u003C\u002Fp>",{"type":35,"title":161,"code":162,"language":163,"highlighted":164},"Authorization code, handed credentials","\u002F\u002F Nuxt 2\nawait $auth.loginWith('drupal-authorization_code', {\n  credentials: { name, pass },\n})","js","\u003Cspan class=\"token comment\">\u002F\u002F Nuxt 2\u003C\u002Fspan>\n\u003Cspan class=\"token keyword\">await\u003C\u002Fspan> $auth\u003Cspan class=\"token punctuation\">.\u003C\u002Fspan>\u003Cspan class=\"token function\">loginWith\u003C\u002Fspan>\u003Cspan class=\"token punctuation\">(\u003C\u002Fspan>\u003Cspan class=\"token string\">'drupal-authorization_code'\u003C\u002Fspan>\u003Cspan class=\"token punctuation\">,\u003C\u002Fspan> \u003Cspan class=\"token punctuation\">{\u003C\u002Fspan>\n  \u003Cspan class=\"token literal-property property\">credentials\u003C\u002Fspan>\u003Cspan class=\"token operator\">:\u003C\u002Fspan> \u003Cspan class=\"token punctuation\">{\u003C\u002Fspan> name\u003Cspan class=\"token punctuation\">,\u003C\u002Fspan> pass \u003Cspan class=\"token punctuation\">}\u003C\u002Fspan>\u003Cspan class=\"token punctuation\">,\u003C\u002Fspan>\n\u003Cspan class=\"token punctuation\">}\u003C\u002Fspan>\u003Cspan class=\"token punctuation\">)\u003C\u002Fspan>",{"type":22,"html":166},"\u003Cul>\u003Cli>No client secret in the app, because underneath it is still authorization code with PKCE.\u003C\u002Fli>\u003Cli>A real Drupal session, which your editors need if they work in Drupal's admin pages through the frontend. \u003Ccode>logout()\u003C\u002Fcode> ends it.\u003C\u002Fli>\u003Cli>Drupal and the frontend have to look like one site to the browser, so it needs the proxy.\u003C\u002Fli>\u003C\u002Ful>",{"type":22,"html":168},"\u003Cp>The second is the \u003Cstrong>password grant\u003C\u002Fstrong>. I shipped it in \u003Ccode>0.4.0\u003C\u002Fcode>, when Simple OAuth 5 still had the grant. The 6.x branch never did, so upgrading took it away. Thankfully \u003Ccode>0.5.0\u003C\u002Fcode> and \u003Ca href=\"https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Fsimple_oauth_password_grant\">Simple OAuth Password Grant\u003C\u002Fa> get it running again:\u003C\u002Fp>",{"type":35,"title":170,"code":171,"language":163,"highlighted":172},"Password grant, through the server route","\u002F\u002F Nuxt 2\nawait $auth.loginWith('drupal-password', {\n  data: { username, password },\n})","\u003Cspan class=\"token comment\">\u002F\u002F Nuxt 2\u003C\u002Fspan>\n\u003Cspan class=\"token keyword\">await\u003C\u002Fspan> $auth\u003Cspan class=\"token punctuation\">.\u003C\u002Fspan>\u003Cspan class=\"token function\">loginWith\u003C\u002Fspan>\u003Cspan class=\"token punctuation\">(\u003C\u002Fspan>\u003Cspan class=\"token string\">'drupal-password'\u003C\u002Fspan>\u003Cspan class=\"token punctuation\">,\u003C\u002Fspan> \u003Cspan class=\"token punctuation\">{\u003C\u002Fspan>\n  \u003Cspan class=\"token literal-property property\">data\u003C\u002Fspan>\u003Cspan class=\"token operator\">:\u003C\u002Fspan> \u003Cspan class=\"token punctuation\">{\u003C\u002Fspan> username\u003Cspan class=\"token punctuation\">,\u003C\u002Fspan> password \u003Cspan class=\"token punctuation\">}\u003C\u002Fspan>\u003Cspan class=\"token punctuation\">,\u003C\u002Fspan>\n\u003Cspan class=\"token punctuation\">}\u003C\u002Fspan>\u003Cspan class=\"token punctuation\">)\u003C\u002Fspan>",{"type":22,"html":174},"\u003Cul>\u003Cli>No redirect, and no proxy needed: the credentials go to Drupal's token endpoint through Druxt Auth's own server route.\u003C\u002Fli>\u003Cli>That route needs a server, so a statically generated site is out.\u003C\u002Fli>\u003Cli>Tokens and nothing else, so Drupal's own pages stay anonymous until you set \u003Ccode>passwordSession\u003C\u002Fcode>, which does need the proxy.\u003C\u002Fli>\u003C\u002Ful>",{"type":22,"html":176},"\u003Cp>Neither needs a form from you. \u003Ccode>0.5.0\u003C\u002Fcode> ships the sign-in too, a \u003Ccode>DruxtAuthLogin\u003C\u002Fcode> component and a Nuxt page at \u003Ccode>\u002Fuser\u002Flogin\u003C\u002Fcode>. Add \u003Ccode>pages\u002Fuser\u002Flogin.vue\u003C\u002Fcode> to replace the page, or a \u003Ccode>DruxtAuthLoginDefault\u003C\u002Fcode> component to theme the form.\u003C\u002Fp>",{"type":17,"title":178,"layout":18,"regions":179},"What the login form was doing for you",{"content":180},[181,183,189,191],{"type":22,"html":182},"\u003Cp>Both post credentials to an endpoint rather than to Drupal's login form, and that form is where Drupal hangs the rest of logging in. \u003Ca href=\"https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Ftfa\">TFA\u003C\u002Fa> interposes there. So does a forced password change, a terms-of-service gate, and anything else that alters it. Skip the form and you skip all of that, and so does anyone else who has the password.\u003C\u002Fp>",{"type":44,"alt":184,"caption":185,"width":186,"height":187,"src":188},"Drupal's authorization dialog: You are allowing druxtjs.org to, three role scopes listed, with Allow and Deny buttons","\u003Cp>Drupal asking the visitor to allow the frontend. The redirect shows this, and the login form before it. Neither grant shows either screen.\u003C\u002Fp>",880,265,"\u002Fimages\u002Fwriting\u002Fdruxt-auth-050-two-ways-to-sign-in-20260926\u002Fdruxt-auth-consent-screen.png",{"type":22,"html":190},"\u003Cp>Rate limiting still runs, in separate counters. Both read their limits from \u003Ccode>user.flood\u003C\u002Fcode>, so the numbers look the same, while the credential sign-in registers under \u003Ccode>user.http_login\u003C\u002Fcode> and the password grant under \u003Ccode>oauth2_password_grant.failed_login_user\u003C\u002Fcode>. Separate counters mean separate budgets, so five attempts per account becomes ten. Clearing the core flood entries will not release someone locked out by the other.\u003C\u002Fp>",{"type":22,"html":192},"\u003Cp>None of that makes either grant wrong. It makes them a trade, because the trip to Drupal is what ran those checks. If you need them, call \u003Ccode>loginWith\u003C\u002Fcode> without credentials and the old flow comes back, Drupal's login page and all. That is how I run two factor on another site. It works, but it means the full round trip every time, and making that less ugly is the next thing I want to fix.\u003C\u002Fp>",{"type":17,"title":194,"layout":18,"regions":195},"What you have to get right",{"content":196},[197,199,203,205,207],{"type":22,"html":198},"\u003Cp>You need to enable \u003Ca href=\"https:\u002F\u002Fdruxtjs.org\u002Fhow-to\u002Fproxy\">the Druxt proxy\u003C\u002Fa> for the \u003Cstrong>authorization code grant\u003C\u002Fstrong>:\u003C\u002Fp>",{"type":35,"title":200,"code":201,"language":163,"highlighted":202},"nuxt.config.js","druxt: {\n  proxy: { api: true },\n}","\u003Cspan class=\"token literal-property property\">druxt\u003C\u002Fspan>\u003Cspan class=\"token operator\">:\u003C\u002Fspan> \u003Cspan class=\"token punctuation\">{\u003C\u002Fspan>\n  \u003Cspan class=\"token literal-property property\">proxy\u003C\u002Fspan>\u003Cspan class=\"token operator\">:\u003C\u002Fspan> \u003Cspan class=\"token punctuation\">{\u003C\u002Fspan> \u003Cspan class=\"token literal-property property\">api\u003C\u002Fspan>\u003Cspan class=\"token operator\">:\u003C\u002Fspan> \u003Cspan class=\"token boolean\">true\u003C\u002Fspan> \u003Cspan class=\"token punctuation\">}\u003C\u002Fspan>\u003Cspan class=\"token punctuation\">,\u003C\u002Fspan>\n\u003Cspan class=\"token punctuation\">}\u003C\u002Fspan>",{"type":22,"html":204},"\u003Cp>It puts Drupal and the frontend on one origin, which is what lets the session cookie from the JSON login reach the authorize step. Without it the sign-in falls back to the redirect. On separate domains the cookie is third party, which leaves the redirect as the only option there, and none of this applies to the password grant.\u003C\u002Fp>",{"type":22,"html":206},"\u003Cp>Consumers are next. A Consumer cannot be public and confidential at once, so a site running both flows needs two, with \u003Ccode>passwordClientId\u003C\u002Fcode> for the second. It also has to authorize automatically, or the visitor sees Drupal's consent page anyway. On Simple OAuth 6 you need an OAuth2 scope too, because it refuses every authorization request until one exists.\u003C\u002Fp>",{"type":22,"html":208},"\u003Cp>The last is behaviour, not configuration. A Drupal session already open in the browser is refused, rather than signing the visitor in as whoever left it there. The error sets \u003Ccode>sessionInUse\u003C\u002Fcode> so your form can say why. To end that session instead, point \u003Ccode>sessionLogout\u003C\u002Fcode> at a route you write yourself in Drupal. Core will not do it.\u003C\u002Fp>",{"type":17,"title":210,"layout":18,"regions":211},"Who put the password grant back",{"content":212},[213,215,217,219,221,223],{"type":22,"html":214},"\u003Cp>The password grant was never Druxt Auth's to give. Only Drupal's OAuth server can mint a token.\u003C\u002Fp>",{"type":22,"html":216},"\u003Cp>\u003Ca href=\"https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Fsimple_oauth_password_grant\">Simple OAuth Password Grant\u003C\u002Fa> puts it back, maintained by \u003Ca href=\"https:\u002F\u002Fwww.drupal.org\u002Fu\u002Fnimoatwoodway\">Christoph Niedermoser\u003C\u002Fa> and \u003Ca href=\"https:\u002F\u002Fwww.drupal.org\u002Fu\u002Fchfoidl\">Christian Foidl\u003C\u002Fa>. They make the case for it themselves:\u003C\u002Fp>",{"type":22,"html":218},"\u003Cblockquote>\u003Cp>The PasswordGrant was part of the Simple OAuth module in Version 5 but got removed in Version 6 because the \u003Ca href=\"https:\u002F\u002Fdatatracker.ietf.org\u002Fdoc\u002Fhtml\u002Fdraft-ietf-oauth-security-topics\">OAuth2 best current practices\u003C\u002Fa> removed the PasswordGrant.\u003C\u002Fp>\u003Cp>However, when using Drupal in a decoupled scenario as a pure backend, you can trust your frontend application.\u003C\u002Fp>\u003Cp>For best user experience, the user must be able to input their login credentials on the Drupal frontend (which is decoupled), so the PasswordGrant makes sense here.\u003C\u002Fp>\u003C\u002Fblockquote>",{"type":22,"html":220},"\u003Cp>Thank you both for your contribution.\u003C\u002Fp>",{"type":22,"html":222},"\u003Cp>If either is useful to you, \u003Ccode>0.5.0\u003C\u002Fcode> is out now:\u003C\u002Fp>",{"type":35,"title":224,"code":225,"language":72,"highlighted":226},"Install","composer require 'drupal\u002Fsimple_oauth_password_grant'\nnpm install druxt-auth@^0.5","\u003Cspan class=\"token function\">composer\u003C\u002Fspan> require \u003Cspan class=\"token string\">'drupal\u002Fsimple_oauth_password_grant'\u003C\u002Fspan>\n\u003Cspan class=\"token function\">npm\u003C\u002Fspan> \u003Cspan class=\"token function\">install\u003C\u002Fspan> druxt-auth@^0.5",{"type":17,"layout":18,"regions":228},{"content":229},[230],{"type":117,"description":231,"url":232,"gitpod":120},"\u003Cp>Druxt Auth, and the example app that runs both flows against a real Drupal. Sponsorship is what keeps Druxt maintained.\u003C\u002Fp>","https:\u002F\u002Fgithub.com\u002Fdruxt\u002Fdruxt-auth","\u002Fwriting\u002Fdruxt-auth-050-two-ways-to-sign-in-20260926","4 min",{"loc":233},"articles-data\u002Fdruxt-auth-050-two-ways-to-sign-in-20260926","e_-OfmacF2xABf1NAvnWzDgottjhOIZc94xtZDMRuM4",{"id":239,"title":240,"articleType":7,"categories":241,"date":242,"description":243,"extension":13,"meta":244,"paragraphs":245,"path":342,"readingTime":343,"sitemap":344,"stem":345,"__hash__":346},"articleEntries\u002Farticles-data\u002Fdruxt-drupal-13x-resource-list-yours-20260909.json","Druxt (for Drupal) 1.3.x; the resource list is yours",[9,136,10],"2026-09-09T19:30:00+10:00","Druxt's Drupal module answers for twelve JSON:API resources, hardcoded, all of them describing structure. 1.3.0 makes that list yours, and here's what I'd add to mine. Any JSON:API client benefits, not only Druxt.",{},[246,255,266,293,301,317,327,335],{"type":17,"layout":18,"regions":247},{"content":248},[249,251,253],{"type":22,"html":250},"\u003Cp>Druxt's Drupal module carries a list of twelve JSON:API resources it answers for. It's been the same twelve since 2021, hardcoded in a PHP array, and changing it has meant carrying a patch.\u003C\u002Fp>",{"type":22,"html":252},"\u003Cp>1.3.0, tagged today, makes that list yours. The twelve stay exactly as they are, so nothing a site exposes changes when it updates. What is new is being able to choose, and the first thing I would choose is the one my frontend has always had to guess at: the toolbar an administrator configured for a text format.\u003C\u002Fp>\u003Cp>A CORS default ships in the same release. If you keep a proxy rule in front of your frontend so that authenticated calls succeed, this is the release where you delete it.\u003C\u002Fp>",{"type":22,"html":254},"\u003Cp>The module name suggests otherwise, but this is a Drupal-side change. Any client holding the right permission gets the same reads.\u003C\u002Fp>",{"type":17,"title":256,"layout":18,"regions":257},"What it answers today",{"content":258},[259,261,264],{"type":22,"html":260},"\u003Cp>Anyone holding the \u003Ccode>access druxt resources\u003C\u002Fcode> permission can read these, whatever access control would otherwise have said:\u003C\u002Fp>",{"type":35,"title":262,"code":263,"language":38},"The list, as it stands","block--block\nconfigurable_language--configurable_language\nentity_form_display--entity_form_display\nentity_form_mode--entity_form_mode\nentity_view_display--entity_view_display\nentity_view_mode--entity_view_mode\nfield_config--field_config\nfield_storage_config--field_storage_config\njsonapi_resource_config--jsonapi_resource_config\nmenu--menu\nmenu_link_content--menu_link_content\nview--view",{"type":22,"html":265},"\u003Cp>Every one describes structure, and all of it is configuration, with one exception: \u003Ccode>menu_link_content\u003C\u002Fcode> is content, and we will come back to it. None of them describes how the site prefers things to look or behave, and with the list compiled in, nobody could add one that did.\u003C\u002Fp>",{"type":17,"title":267,"layout":18,"regions":268},"Starting with rich text",{"content":269},[270,272,274,276,281,283,285,289,291],{"type":22,"html":271},"\u003Cp>A frontend offering an editing experience has no way to read the toolbar an administrator configured, so it ships whatever buttons its developer chose and hopes they match.\u003C\u002Fp>",{"type":22,"html":273},"\u003Cp>The reason it cannot read it is the interesting part. The only core permission that grants access to a text format's configuration is \u003Cstrong>administer filters\u003C\u002Fstrong>, which core itself flags \u003Ccode>restrict access\u003C\u002Fcode>. Hand it to an author and they can rewrite the text format, one of the shorter routes to an XSS. So the choice has been between a permission you cannot give them and a frontend guessing at a toolbar.\u003C\u002Fp>",{"type":22,"html":275},"\u003Cp>A checkbox is the third option, on a new settings form at \u003Cem>Configuration &gt; Web services &gt; Druxt\u003C\u002Fem>. It grants read where \u003Cstrong>administer filters\u003C\u002Fstrong> grants write, and it grants it to everyone holding \u003Ccode>access druxt resources\u003C\u002Fcode> instead of to one trusted account. List \u003Ccode>editor--editor\u003C\u002Fcode> and the frontend reads the toolbar and builds from it; change the toolbar in Drupal and the editor changes, with no rebuild: 10 buttons for \u003Ccode>basic_html\u003C\u002Fcode>, 16 for \u003Ccode>full_html\u003C\u002Fcode>.\u003C\u002Fp>",{"type":44,"src":277,"alt":278,"caption":279,"width":151,"height":280},"\u002Fimages\u002Fwriting\u002Fdruxt-130-toolbars.png","Two toolbars stacked, each labelled with one word. Above, labelled Drupal: the buttons sit in grey tiles and the separators are tiles of their own. Below, labelled Frontend: the same buttons in the same order in a plain row with thin dividers. In both, reading left to right: bold, italic, strikethrough, superscript, subscript, code, remove format, link, bulleted list, numbered list, block quote, image, table, horizontal line, a heading dropdown, code block and source editing.","\u003Cp>The same toolbar, twice. Drupal draws the separators as draggable tiles because that screen is for editing the toolbar; the frontend draws them as dividers.\u003C\u002Fp>",744,{"type":22,"html":282},"\u003Cp>Which filters run is a second tick, on \u003Ccode>filter_format--filter_format\u003C\u002Fcode>. It tells a frontend whether a caption arrives in a \u003Ccode>data-caption\u003C\u002Fcode> attribute or in the markup. Fetch it once first: JSON:API hands over whole entities, so that is every format on the site and each one's filter settings, an open blob contrib modules fill with their own keys.\u003C\u002Fp>",{"type":22,"html":284},"\u003Cp>What comes back is Drupal's vocabulary, not CKEditor's. \u003Ccode>drupalInsertImage\u003C\u002Fcode> is Drupal's name for \u003Ccode>uploadImage\u003C\u002Fcode>, and an item your build has not loaded is dropped with a console warning rather than an error, so the editor comes up fine, quietly missing buttons the format says it has.\u003C\u002Fp>",{"type":35,"title":286,"code":287,"language":163,"highlighted":288},"Reading the toolbar, server side","\u002F\u002F Nuxt 2. fetch() runs on the server; druxt-site injects $druxt.\nasync fetch() {\n  \u002F\u002F A string: an object does not survive the query serialiser, and 400s.\n  const { data } = await this.$druxt.getCollection(\n    'editor--editor',\n    'filter[drupal_internal__format]=basic_html',\n  )\n  this.items = ((data[0] || {}).attributes || {}).settings.toolbar.items || []\n}","\u003Cspan class=\"token comment\">\u002F\u002F Nuxt 2. fetch() runs on the server; druxt-site injects $druxt.\u003C\u002Fspan>\n\u003Cspan class=\"token keyword\">async\u003C\u002Fspan> \u003Cspan class=\"token function\">fetch\u003C\u002Fspan>\u003Cspan class=\"token punctuation\">(\u003C\u002Fspan>\u003Cspan class=\"token punctuation\">)\u003C\u002Fspan> \u003Cspan class=\"token punctuation\">{\u003C\u002Fspan>\n  \u003Cspan class=\"token comment\">\u002F\u002F A string: an object does not survive the query serialiser, and 400s.\u003C\u002Fspan>\n  \u003Cspan class=\"token keyword\">const\u003C\u002Fspan> \u003Cspan class=\"token punctuation\">{\u003C\u002Fspan> data \u003Cspan class=\"token punctuation\">}\u003C\u002Fspan> \u003Cspan class=\"token operator\">=\u003C\u002Fspan> \u003Cspan class=\"token keyword\">await\u003C\u002Fspan> \u003Cspan class=\"token keyword\">this\u003C\u002Fspan>\u003Cspan class=\"token punctuation\">.\u003C\u002Fspan>$druxt\u003Cspan class=\"token punctuation\">.\u003C\u002Fspan>\u003Cspan class=\"token function\">getCollection\u003C\u002Fspan>\u003Cspan class=\"token punctuation\">(\u003C\u002Fspan>\n    \u003Cspan class=\"token string\">'editor--editor'\u003C\u002Fspan>\u003Cspan class=\"token punctuation\">,\u003C\u002Fspan>\n    \u003Cspan class=\"token string\">'filter[drupal_internal__format]=basic_html'\u003C\u002Fspan>\u003Cspan class=\"token punctuation\">,\u003C\u002Fspan>\n  \u003Cspan class=\"token punctuation\">)\u003C\u002Fspan>\n  \u003Cspan class=\"token keyword\">this\u003C\u002Fspan>\u003Cspan class=\"token punctuation\">.\u003C\u002Fspan>items \u003Cspan class=\"token operator\">=\u003C\u002Fspan> \u003Cspan class=\"token punctuation\">(\u003C\u002Fspan>\u003Cspan class=\"token punctuation\">(\u003C\u002Fspan>data\u003Cspan class=\"token punctuation\">[\u003C\u002Fspan>\u003Cspan class=\"token number\">0\u003C\u002Fspan>\u003Cspan class=\"token punctuation\">]\u003C\u002Fspan> \u003Cspan class=\"token operator\">||\u003C\u002Fspan> \u003Cspan class=\"token punctuation\">{\u003C\u002Fspan>\u003Cspan class=\"token punctuation\">}\u003C\u002Fspan>\u003Cspan class=\"token punctuation\">)\u003C\u002Fspan>\u003Cspan class=\"token punctuation\">.\u003C\u002Fspan>attributes \u003Cspan class=\"token operator\">||\u003C\u002Fspan> \u003Cspan class=\"token punctuation\">{\u003C\u002Fspan>\u003Cspan class=\"token punctuation\">}\u003C\u002Fspan>\u003Cspan class=\"token punctuation\">)\u003C\u002Fspan>\u003Cspan class=\"token punctuation\">.\u003C\u002Fspan>settings\u003Cspan class=\"token punctuation\">.\u003C\u002Fspan>toolbar\u003Cspan class=\"token punctuation\">.\u003C\u002Fspan>items \u003Cspan class=\"token operator\">||\u003C\u002Fspan> \u003Cspan class=\"token punctuation\">[\u003C\u002Fspan>\u003Cspan class=\"token punctuation\">]\u003C\u002Fspan>\n\u003Cspan class=\"token punctuation\">}\u003C\u002Fspan>",{"type":22,"html":290},"\u003Cp>All of which is me saying: expect a Druxt CKEditor module in the future. Mounting the editor is where the work actually is. CKEditor 5 uses static class blocks, which the bundler Nuxt 2 ships cannot parse, so today you load it from a script tag and match the version Drupal ships rather than the one npm defaults to. That is exactly the sort of thing a module should absorb so nobody else meets it.\u003C\u002Fp>",{"type":22,"html":292},"\u003Cp>Neither is ticked by default. Updating writes the same twelve into configuration and stops there, and nothing on the list is readable by anyone until \u003Ccode>access druxt resources\u003C\u002Fcode> is granted, which installing grants to nobody. Changing the list needs \u003Ccode>administer druxt\u003C\u002Fcode>, which ships restricted.\u003C\u002Fp>",{"type":17,"title":294,"layout":18,"regions":295},"Then everything else",{"content":296},[297,299],{"type":22,"html":298},"\u003Cp>What else is a frontend inventing? All three of these are configuration entities, so they are already in that checkbox list, unticked:\u003C\u002Fp>",{"type":22,"html":300},"\u003Cul>\u003Cli>\u003Cstrong>Image styles.\u003C\u002Fstrong> Effects carry the dimensions a \u003Ccode>srcset\u003C\u002Fcode> needs. The derivative URLs are solved already, by \u003Ca href=\"https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Fjsonapi_image_styles\">JSON:API Image Styles\u003C\u002Fa> and \u003Ca href=\"https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Fconsumer_image_styles\">Consumer Image Styles\u003C\u002Fa>, after \u003Ca href=\"https:\u002F\u002Fwww.lullabot.com\u002Farticles\u002Fdecoupled-drupal-hard-problems-image-styles\">Lullabot named it in 2018\u003C\u002Fa>\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Editorial workflow.\u003C\u002Fstrong> Content moderation's states and transitions would let an editing interface show where a document sits and which moves are legal, instead of a hardcoded draft-and-published pair\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Bulk actions.\u003C\u002Fstrong> \u003Ccode>action--action\u003C\u002Fcode> carries every action a site has configured, so a decoupled content list could offer exactly those\u003C\u002Fli>\n\u003C\u002Ful>",{"type":17,"title":302,"layout":18,"regions":303},"What it will not answer for",{"content":304},[305,307,309,311],{"type":22,"html":306},"\u003Cp>Druxt answers Drupal's entity access check with a yes for any listed route, and lifts JSON:API's limit on filtering by fields the requester could not otherwise see. A listed resource is readable by anyone holding \u003Ccode>access druxt resources\u003C\u002Fcode>, whatever the site would otherwise have said, and on a decoupled site that permission often goes to anonymous.\u003C\u002Fp>",{"type":22,"html":308},"\u003Cp>The list has one axis. It says what, never who: the same yes, site-wide, for everyone holding the permission. That suits configuration, which answers the same whoever is asking. Content varies per entity by published state, owner and field access, so one yes is never right for it. \u003Ccode>user--user\u003C\u002Fcode> would hand over every account, blocked ones included, and enough filtering to enumerate them.\u003C\u002Fp>",{"type":22,"html":310},"\u003Cp>\u003Ccode>menu_link_content\u003C\u002Fcode> is the exception, and it is content, grandfathered because it shipped in the hardcoded list. It is also the resource that gives a frontend the least, so I maintain \u003Ca href=\"https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Fjsonapi_menu_items\">JSON:API Menu Items\u003C\u002Fa> to cover the gap.\u003C\u002Fp>",{"type":44,"src":312,"alt":313,"caption":314,"width":315,"height":316},"\u002Fimages\u002Fwriting\u002Fdruxt-130-settings-form.png","The Druxt settings form at Configuration, Web services, Druxt. A list headed Exposed resources with a checkbox per configuration entity type. Ticked: block, editor, entity_form_display, entity_form_mode, entity_view_display, entity_view_mode, field_config, field_storage_config, menu, menu_link_content, view. Unticked: action, base_field_override, block_content_type, date_format, filter_format, image_style, media_type, node_type, oauth2_scope, oauth2_token_type, taxonomy_vocabulary, user_role. No content entity types are offered. Help text below reads that a checked resource is readable by anyone with the access druxt resources permission, whatever the site would otherwise allow.","\u003Cp>Configuration entity types only, and no content ones offered at all. \u003Ccode>editor--editor\u003C\u002Fcode> and \u003Ccode>filter_format--filter_format\u003C\u002Fcode> are separate ticks, and the help text under the list says outright that a ticked resource is readable by anyone holding the permission.\u003C\u002Fp>",1280,900,{"type":17,"title":318,"layout":18,"regions":319},"CORS, and the proxy rule you can delete",{"content":320},[321,323,325],{"type":22,"html":322},"\u003Cp>One more thing, and it takes a step out of everyone's setup. On a site that has not configured CORS itself, Druxt turns it on and allows every header, and now sets \u003Ccode>allowedMethods\u003C\u002Fcode> too. That list is what the library underneath advertises methods from, and core ships it empty, so the browser refused the preflight and the request never left.\u003C\u002Fp>",{"type":22,"html":324},"\u003Cp>Anonymous \u003Ccode>GET\u003C\u002Fcode> was never affected, since a simple request is not preflighted. What changes is everything else: writes, and reads that set an \u003Ccode>Authorization\u003C\u002Fcode> header. If you keep a proxy rule or a middleware in front of your frontend so that authenticated calls succeed, this is the release where you delete it. Worth checking rather than assuming, because a refused preflight answers 204 with a clean log, and \u003Ccode>curl\u003C\u002Fcode> never reproduces it: only a browser enforces the response.\u003C\u002Fp>",{"type":22,"html":326},"\u003Cp>A site that configured \u003Ccode>cors.config\u003C\u002Fcode> itself is untouched, and credentials stay off, so cookies and sessions still do not travel cross-origin. An \u003Ccode>Authorization\u003C\u002Fcode> header does. The \u003Ca href=\"https:\u002F\u002Fdruxtjs.org\u002F\">documentation site\u003C\u002Fa> was rebuilt around \u003Ca href=\"https:\u002F\u002Fdruxtjs.org\u002Ftutorials\">tutorials\u003C\u002Fa> last week, and the \u003Ca href=\"https:\u002F\u002Fdruxtjs.org\u002Ftutorials\u002Fauthentication\">login flow\u003C\u002Fa> is the one to start with if authenticated requests are what you have been putting off.\u003C\u002Fp>",{"type":17,"title":328,"layout":18,"regions":329},"What are you working around?",{"content":330},[331,333],{"type":22,"html":332},"\u003Cp>Enough about what I would tick. What I want to know is what you are already working around. Anyone building against Drupal from outside it has written something that guesses at a value Drupal already holds. Mine was a toolbar. It is a checkbox now.\u003C\u002Fp>",{"type":22,"html":334},"\u003Cp>So what is yours, and what would you build if you could simply read it?\u003C\u002Fp>",{"type":17,"layout":18,"regions":336},{"content":337},[338],{"type":117,"description":339,"url":340,"gitpod":120,"drupalUrl":341},"\u003Cp>The Drupal module this ships in. If your projects lean on modules like it, sponsoring is what keeps them maintained.\u003C\u002Fp>","https:\u002F\u002Fgithub.com\u002Fdruxt\u002Fdruxt_drupal","https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Fdruxt","\u002Fwriting\u002Fdruxt-drupal-13x-resource-list-yours-20260909","6 min",{"loc":342},"articles-data\u002Fdruxt-drupal-13x-resource-list-yours-20260909","J8J4Zt8VIrFsKcyCYdp6v2QMDWTrK5SEKG74jRVcQE0",{"id":348,"title":349,"articleType":7,"categories":350,"date":351,"description":352,"extension":13,"meta":353,"paragraphs":354,"path":439,"readingTime":234,"sitemap":440,"stem":441,"__hash__":442},"articleEntries\u002Farticles-data\u002Fdrupal-site-settings-over-jsonapi-consumer-20260826.json","Drupal site settings over JSON:API, per consumer",[9,136,10],"2026-08-26T19:20:00+10:00","Run the same decoupled frontend twice with two consumer IDs and get two differently branded sites. Decoupled Settings serves the site and theme config Drupal already holds over JSON:API, with per-consumer overrides. Four years ago I guessed the answer would be Consumers plus theme settings. Turns out it was.",{},[355,362,368,374,404,414,426,432],{"type":17,"layout":18,"regions":356},{"content":357},[358,360],{"type":22,"html":359},"\u003Cp>In April 2022 I wrote about \u003Ca href=\"\u002Fwriting\u002Fdecoupling-configuration-config-pages-20220412\">decoupling configuration with Config Pages\u003C\u002Fa>, and ended it with a guess at where I'd go next:\u003C\u002Fp>\n\n\u003Cblockquote>\u003Cp>One of my future experiments with Druxt will be to look at the options of using the Drupal Consumers module alongside Drupal theme settings as a solution.\u003C\u002Fp>\u003C\u002Fblockquote>",{"type":22,"html":361},"\u003Cp>That experiment is now a module. \u003Ca href=\"https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Fdecoupled_settings\">Decoupled Settings\u003C\u002Fa> serves the site and theme configuration Drupal already holds over JSON:API, and lets every frontend override just the values it needs. It went up on Drupal.org this week.\u003C\u002Fp>",{"type":17,"title":363,"layout":18,"regions":364},"What core doesn't give you",{"content":365},[366],{"type":22,"html":367},"\u003Cp>Core's JSON:API is an entity API. Content entities and config entities alike, so node types, image styles and views are all in there. What it has never exposed is simple configuration, and there's a good argument that it shouldn't by default, because plenty of what sits in \u003Ccode>system.site\u003C\u002Fcode> is nobody's business.\u003C\u002Fp>\n\n\u003Cp>But a decoupled frontend still needs the boring stuff:\u003C\u002Fp>\n\n\u003Cul>\u003Cli>The site name, for the document title\u003C\u002Fli>\n\u003Cli>The slogan\u003C\u002Fli>\n\u003Cli>The logo and the favicon\u003C\u002Fli>\n\u003Cli>The front page path, so the router knows what \"home\" means\u003C\u002Fli>\n\u003C\u002Ful>\n\n\u003Cp>So every decoupled build solves it locally, and most of the ways to solve it end up keeping a second copy of the site name somewhere.\u003C\u002Fp>",{"type":17,"title":369,"layout":18,"regions":370},"Isn't that what Config Pages is for?",{"content":371},[372],{"type":22,"html":373},"\u003Cp>Config Pages is for settings \u003Cem>you\u003C\u002Fem> invent: define a type, add the fields your app needs, done. That job hasn't changed, and it's still on my sites.\u003C\u002Fp>\n\n\u003Cp>Where it gets awkward is settings Drupal already stores. Model the site name as a field on a Config Page and the site name exists in two places, and something has to keep them in step, and sooner or later something won't.\u003C\u002Fp>",{"type":17,"title":375,"layout":18,"regions":376},"How it works",{"content":377},[378,380,386,388,394,396,399,402],{"type":22,"html":379},"\u003Cp>So the module doesn't store settings. It reads them from the config objects that already hold them, and a consumer stores only what it changes.\u003C\u002Fp>",{"type":44,"alt":381,"caption":382,"width":383,"height":384,"src":385},"The per-consumer overrides form for a consumer named Partner Portal, filtered to system.site. Columns are Setting, Inherited value, Override and Value for this consumer. system.site:name and system.site:slogan are ticked and overridden to 'Partner Portal' and 'Same code, different consumer'; langcode, page.403, page.404 and page.front are unticked and inherited.","\u003Cp>Tick a setting to override it for this consumer. Everything unticked keeps following the site.\u003C\u002Fp>",1336,1022,"\u002Fimages\u002Fwriting\u002Fdecoupled-settings-consumer-overrides.png",{"type":22,"html":387},"\u003Cp>Tick a setting and it's yours. Leave it alone and it keeps following the site. Tick it and leave the value blank and that frontend doesn't show a slogan at all, which is a different thing again from clearing the override and going back to inheriting.\u003C\u002Fp>\n\n\u003Cp>What's exposed at all is bounded twice: the config objects you list, and within those, the keys typed config schema declares. On install that's \u003Ccode>system.site\u003C\u002Fcode> plus the active theme, and both of \u003Ccode>system.site\u003C\u002Fcode>'s email keys ship excluded. The settings form shows exactly how wide the exposure is, unsaved changes included, so you can trim it to the keys you want before anything ships.\u003C\u002Fp>",{"type":44,"alt":389,"caption":390,"width":391,"height":392,"src":393},"The Decoupled Settings configuration form: an Exposed configuration list containing system.site, a checkbox to expose the active theme settings, an Excluded settings box listing system.site:mail and system.site:mail_notification, and a 'What a frontend will read' table showing each setting with its global value.","\u003Cp>The exposure list, the keys it holds back, and what a frontend gets from what's left. Filtered to \u003Ccode>system.site\u003C\u002Fcode> here, so the theme's fourteen keys aren't in shot.\u003C\u002Fp>",1016,1358,"\u002Fimages\u002Fwriting\u002Fdecoupled-settings-exposure-form.png",{"type":22,"html":395},"\u003Cp>Reading it is one GET:\u003C\u002Fp>",{"type":35,"title":397,"code":398},"Reading settings as a consumer","curl \"https:\u002F\u002Fdrupal.example.com\u002Fjsonapi\u002Fdecoupled\u002Fsettings?consumerId=partner_frontend\"",{"type":35,"title":400,"code":401},"Abbreviated: 7 of the 23 keys, otherwise as returned","{\n  \"data\": {\n    \"type\": \"decoupled_settings--settings\",\n    \"id\": \"decoupled-settings\",\n    \"attributes\": {\n      \"settings\": {\n        \"system.site\": {\n          \"name\": \"Partner Portal\",\n          \"slogan\": \"Same code, different consumer\",\n          \"page\": { \"front\": \"\u002Fnode\" }\n        },\n        \"olivero.settings\": {\n          \"favicon\": { \"url\": \"\u002Fcore\u002Fthemes\u002Folivero\u002Ffavicon.ico\", \"use_default\": true },\n          \"logo\": { \"url\": \"\u002Fcore\u002Fthemes\u002Folivero\u002Flogo.svg\", \"use_default\": true }\n        }\n      },\n      \"consumer\": \"partner_frontend\"\n    }\n  }\n}",{"type":22,"html":403},"\u003Cp>The logo and favicon come back as resolved URLs, through core's own theme settings resolution and its fallbacks. Responses collect the config cache tags of every object that contributed, so an editor changing the site name invalidates them with nobody writing a hook.\u003C\u002Fp>\n\n\u003Cp>With \u003Ca href=\"https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Fsimple_oauth\">Simple OAuth\u003C\u002Fa> it's simpler still: a client credentials token identifies the consumer by itself, no header and no query parameter, because the OAuth client and the settings consumer are the same entity.\u003C\u002Fp>",{"type":17,"title":405,"layout":18,"regions":406},"One backend, many frontends",{"content":407},[408,410,412],{"type":22,"html":409},"\u003Cp>A consumer is a name on a request. Point two builds of the same frontend at one backend, have each identify as a different consumer, and each comes up as its own site: its own name, its own slogan, its own logo and favicon. Nothing in the code differs between them, only an environment variable.\u003C\u002Fp>",{"type":22,"html":411},"\u003Cp>Read the settings at build time and bake them into the artifact, and the artifact doesn't depend on Drupal at runtime, at the cost of a rebuild whenever a setting changes. Read them at runtime and the cache tags start earning their keep. Either way it's one request, so it matters very little what the frontend is built with.\u003C\u002Fp>\n\n\u003Cp>A consumer gets its own name, slogan, front page and branding assets. Menus, regions, layouts and per-market content are still yours to solve.\u003C\u002Fp>",{"type":22,"html":413},"\u003Cp>If you're on Druxt, a module that wires all of this into the build is close behind, for the current Druxt release. It identifies the app as a consumer, reads the settings, and applies the site name and favicon to the document head. It also bakes the whole resolved set into Nuxt's runtime config, so \u003Ccode>$config.decoupledSettings['system.site'].name\u003C\u002Fcode> works anywhere in the app.\u003C\u002Fp>",{"type":17,"title":415,"layout":18,"regions":416},"Where it stands",{"content":417},[418,420,422,424],{"type":22,"html":419},"\u003Cp>108 tests and 492 assertions across unit, kernel and functional coverage, green on Drupal 10 and Drupal 11. The first pipeline on drupalcode.org came back green across all eight jobs on its first run, which never happens.\u003C\u002Fp>",{"type":22,"html":421},"\u003Cp>It's \u003Cstrong>1.0.0-beta2\u003C\u002Fstrong>. Drupal's security advisory policy covers stable releases only, and the response shape can still move before 1.0. Adopt now and you're the second consumer of this API, which means you get a say in that shape while it's still soft.\u003C\u002Fp>\n\n\u003Cp>Overrides live on the consumer entity, so they're content rather than config, and they stay in the database rather than travelling with \u003Ccode>drush cim\u003C\u002Fcode>. Multilingual works one way today: exposed values follow language negotiation, but an override applies in every language, so you can translate a setting or brand it per consumer, not both yet.\u003C\u002Fp>",{"type":22,"html":423},"\u003Cp>If any of that is useful, the beta is out now:\u003C\u002Fp>",{"type":35,"title":224,"code":425},"composer require 'drupal\u002Fdecoupled_settings:^1.0@beta'\ndrush en decoupled_settings",{"type":17,"title":427,"layout":18,"regions":428},"What next?",{"content":429},[430],{"type":22,"html":431},"\u003Cp>File (Field) Paths, still next up, and the Druxt half of this behind it.\u003C\u002Fp>\n\n\u003Cp>If you're running decoupled Drupal already, how are you getting the site name into your frontend today? I'd like to know, while the API shape is still soft enough to change.\u003C\u002Fp>",{"type":17,"layout":18,"regions":433},{"content":434},[435],{"type":117,"description":436,"url":437,"gitpod":120,"drupalUrl":438},"\u003Cp>Source on GitHub, project page and issue queue on Drupal.org. If your projects lean on modules like this one, sponsoring is what keeps them actively maintained.\u003C\u002Fp>","https:\u002F\u002Fgithub.com\u002FDecipher\u002Fdecoupled_settings","https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Fdecoupled_settings","\u002Fwriting\u002Fdrupal-site-settings-over-jsonapi-consumer-20260826",{"loc":439},"articles-data\u002Fdrupal-site-settings-over-jsonapi-consumer-20260826","AfWvvQeLG8E0HK9wKF51FKaoMngbUKR6PfbLJ8v2H6s",{"list":444},[445,450,455,460,467,473,482,487,492,499],{"title":446,"field_project_machine_name":447,"project_usage":448,"flag_project_star_user":-1},"Dindent","dindent",{"7.x-1.x":449},"6",{"title":451,"field_project_machine_name":452,"project_usage":453,"flag_project_star_user":-1},"famfamfam.com icons","famfamfam",{"7.x-1.x":454},10,{"title":456,"field_project_machine_name":457,"project_usage":458,"flag_project_star_user":-1},"Better sub-themes","better_subthemes",{"8.x-1.x":459},"1",{"title":461,"field_project_machine_name":462,"project_usage":463,"flag_project_star_user":-1},"Field Tokens","field_tokens",{"7.x-1.x":464,"2.0.x":465,"8.x-1.x":466},428,392,"91",{"title":468,"field_project_machine_name":469,"project_usage":470,"flag_project_star_user":-1},"JSON:API Menu Items","jsonapi_menu_items",{"1.1.x":471,"1.2.x":472},7,4985,{"title":474,"field_project_machine_name":475,"project_usage":476,"flag_project_star_user":-1},"Custom Formatters","custom_formatters",{"6.x-1.x":477,"8.x-3.x":478,"4.1.x":479,"7.x-2.x":480,"4.0.x":481},39,89,382,2493,"60",{"title":483,"field_project_machine_name":484,"project_usage":485,"flag_project_star_user":-1},"Decoupled Settings","decoupled_settings",{"1.0.x":486},"15",{"title":488,"field_project_machine_name":489,"project_usage":490,"flag_project_star_user":-1},"Administration Menu select","admin_select",{"7.x-1.x":491,"6.x-1.x":459},169,{"title":493,"field_project_machine_name":494,"project_usage":495,"flag_project_star_user":-1},"DruxtJS","druxt",{"1.0.x":459,"1.3.x":496,"1.1.x":497,"1.2.x":498},1015,"4",122,{"title":500,"field_project_machine_name":501,"project_usage":502,"flag_project_star_user":-1},"File (Field) Paths","filefield_paths",{"5.x-1.x":459,"6.x-2.x":459,"6.x-1.x":503,"7.x-1.x":504,"8.x-1.x":505},551,11264,20323,{"list":507},[508,511,514,517,527,533,539,545,550,556,561,565,570,573,576,579,582,585,589,593],{"title":509,"field_project_machine_name":510,"project_usage":-1,"flag_project_star_user":-1},"SSI","ssi",{"title":512,"field_project_machine_name":513,"project_usage":-1,"flag_project_star_user":-1},"BitTorrent Sync fields","btsync_fields",{"title":515,"field_project_machine_name":516,"project_usage":-1,"flag_project_star_user":-1},"Druxt connect","druxt_connect",{"title":518,"field_project_machine_name":519,"project_usage":520,"flag_project_star_user":-1},"ImageField Tokens","imagefield_tokens",{"5.x-1.x":459,"8.x-2.x":521,"3.0.x":522,"6.x-1.x":523,"7.x-1.x":524,"3.1.x":525,"3.2.x":526},229,18,125,2859,"164","687",{"title":528,"field_project_machine_name":529,"project_usage":530,"flag_project_star_user":-1},"Wysiwyg Fields","wysiwyg_fields",{"7.x-2.x":531,"7.x-1.x":532},"7","31",{"title":534,"field_project_machine_name":535,"project_usage":536,"flag_project_star_user":-1},"Mobile Codes","mobile_codes",{"6.x-1.x":537,"6.x-2.x":454,"7.x-2.x":538},"2",366,{"title":540,"field_project_machine_name":541,"project_usage":542,"flag_project_star_user":-1},"File Aliases","file_aliases",{"6.x-1.x":543,"7.x-1.x":544},27,62,{"title":546,"field_project_machine_name":547,"project_usage":548,"flag_project_star_user":-1},"Drag'n'Drop Uploads","dragndrop_uploads",{"6.x-1.x":531,"7.x-1.x":549},"35",{"title":551,"field_project_machine_name":552,"project_usage":553,"flag_project_star_user":-1},"Wysiwyg ImageField","wysiwyg_imagefield",{"6.x-1.x":554,"7.x-1.x":555},5,"61",{"title":557,"field_project_machine_name":558,"project_usage":559,"flag_project_star_user":-1},"Formatters for Node Reference fields","formatters4nodereference",{"6.x-1.x":560,"7.x-1.x":497},"3",{"title":562,"field_project_machine_name":563,"project_usage":564,"flag_project_star_user":-1},"Formatter Settings","formatter_settings",{"6.x-1.x":449},{"title":566,"field_project_machine_name":567,"project_usage":568,"flag_project_star_user":-1},"Deep Zoom","deepzoom",{"7.x-1.x":569},20,{"title":571,"field_project_machine_name":572,"project_usage":-1,"flag_project_star_user":-1},"Hostmaster Reinstall","hostmaster_reinstall",{"title":574,"field_project_machine_name":575,"project_usage":-1,"flag_project_star_user":-1},"Provision Reinstall","provision_reinstall",{"title":577,"field_project_machine_name":578,"project_usage":-1,"flag_project_star_user":-1},"Hosting Reinstall","hosting_reinstall",{"title":580,"field_project_machine_name":581,"project_usage":-1,"flag_project_star_user":-1},"Render As","renderas",{"title":583,"field_project_machine_name":584,"project_usage":-1,"flag_project_star_user":-1},"Derivicon","derivicon",{"title":586,"field_project_machine_name":587,"project_usage":588,"flag_project_star_user":-1},"Contextual variables","context_variable",{"7.x-1.x":537},{"title":590,"field_project_machine_name":591,"project_usage":592,"flag_project_star_user":-1},"Contextual modules","context_module",{"7.x-1.x":560},{"title":594,"field_project_machine_name":595,"project_usage":596,"flag_project_star_user":-1},"Contextual server variables","context_server_vars",{"7.x-1.x":537},{"list":598},[599,602,605,608,611,614,617,620,623,626,629,632,635,638,641,644,647,650,653,656,659,662,665,668,671,674,677,680,683,686,689,692,695,698,701,704,707,710,713,716,719,722,725,728,731,734,737,740,743,746],{"created":600,"url":601},"1790896260","https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Ffilefield_paths\u002Fissues\u002F3035301#comment-16792233",{"created":603,"url":604},"1790823406","https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Ffilefield_paths\u002Fissues\u002F3035301#comment-16790363",{"created":606,"url":607},"1790819551","https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Ffilefield_paths\u002Fissues\u002F3494240#comment-16790319",{"created":609,"url":610},"1790810840","https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Ffilefield_paths\u002Fissues\u002F3277844#comment-16790231",{"created":612,"url":613},"1790638815","https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Fdruxt\u002Fissues\u002F3407903#comment-16787300",{"created":615,"url":616},"1790632315","https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Fdruxt\u002Fissues\u002F3407903#comment-16787252",{"created":618,"url":619},"1790574427","https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Fdrupal\u002Fissues\u002F3626255#comment-16786412",{"created":621,"url":622},"1789776207","https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Ffilefield_paths\u002Fissues\u002F3035301#comment-16776545",{"created":624,"url":625},"1789776126","https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Ffilefield_paths\u002Fissues\u002F3277844#comment-16776544",{"created":627,"url":628},"1789775713","https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Ffilefield_paths\u002Fissues\u002F3277844#comment-16776542",{"created":630,"url":631},"1789724358","https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Ffilefield_paths\u002Fissues\u002F3494240#comment-16775694",{"created":633,"url":634},"1789723564","https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Ffilefield_paths\u002Fissues\u002F3494240#comment-16775665",{"created":636,"url":637},"1789723559","https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Ffilefield_paths\u002Fissues\u002F3494240#comment-16775664",{"created":639,"url":640},"1789723217","https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Ffilefield_paths\u002Fissues\u002F3494240#comment-16775648",{"created":642,"url":643},"1789586961","https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Ftextimage\u002Fissues\u002F3569464#comment-16773260",{"created":645,"url":646},"1789329321","https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Ffilefield_paths\u002Fissues\u002F3622262#comment-16769120",{"created":648,"url":649},"1789165036","https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Ffilefield_paths\u002Fissues\u002F3622262#comment-16767986",{"created":651,"url":652},"1789092326","https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Ffilefield_paths\u002Fissues\u002F3622262#comment-16766993",{"created":654,"url":655},"1789079510","https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Fdecoupled_router\u002Fissues\u002F3111456#comment-16766889",{"created":657,"url":658},"1789074795","https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Fdecoupled_router\u002Fissues\u002F3111456#comment-16766839",{"created":660,"url":661},"1789074767","https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Fdecoupled_router\u002Fissues\u002F3111456#comment-16766837",{"created":663,"url":664},"1789074760","https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Fdecoupled_router\u002Fissues\u002F3111456#comment-16766835",{"created":666,"url":667},"1789074739","https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Fdecoupled_router\u002Fissues\u002F3111456#comment-16766834",{"created":669,"url":670},"1788920715","https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Fdruxt\u002Fissues\u002F3309969#comment-16764482",{"created":672,"url":673},"1788818455","https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Ffilefield_paths\u002Fissues\u002F3035301#comment-16762452",{"created":675,"url":676},"1788818437","https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Ffilefield_paths\u002Fissues\u002F3035301#comment-16762451",{"created":678,"url":679},"1788768757","https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Fdruxt\u002Fissues\u002F3309969#comment-16761345",{"created":681,"url":682},"1788767371","https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Fdruxt\u002Fissues\u002F3309969#comment-16761316",{"created":684,"url":685},"1788750260","https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Ffilefield_paths\u002Fissues\u002F3619767#comment-16761121",{"created":687,"url":688},"1788746171","https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Ffilefield_paths\u002Fissues\u002F3619767#comment-16761099",{"created":690,"url":691},"1788745468","https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Ffilefield_paths\u002Fissues\u002F3619767#comment-16761083",{"created":693,"url":694},"1788745341","https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Ffilefield_paths\u002Fissues\u002F3045063#comment-16761081",{"created":696,"url":697},"1788594321","https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Fdruxt\u002Fissues\u002F3273228#comment-16759310",{"created":699,"url":700},"1788418391","https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Fdruxt\u002Fissues\u002F3618677#comment-16756416",{"created":702,"url":703},"1788343885","https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Ffilefield_paths\u002Fissues\u002F3045063#comment-16754995",{"created":705,"url":706},"1788343069","https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Ffilefield_paths\u002Fissues\u002F3045063#comment-16754962",{"created":708,"url":709},"1788340410","https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Ffilefield_paths\u002Fissues\u002F3432653#comment-16754902",{"created":711,"url":712},"1788340346","https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Ffilefield_paths\u002Fissues\u002F3616606#comment-16754899",{"created":714,"url":715},"1788244103","https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Ffilefield_paths\u002Fissues\u002F3035301#comment-16753337",{"created":717,"url":718},"1788132203","https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Ffilefield_paths\u002Fissues\u002F3035301#comment-16751914",{"created":720,"url":721},"1787963893","https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Ffilefield_paths\u002Fissues\u002F3419618#comment-16750632",{"created":723,"url":724},"1787898274","https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Ffilefield_paths\u002Fissues\u002F3432653#comment-16749653",{"created":726,"url":727},"1787898260","https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Ffilefield_paths\u002Fissues\u002F3432653#comment-16749652",{"created":729,"url":730},"1787897913","https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Ffilefield_paths\u002Fissues\u002F3432653#comment-16749648",{"created":732,"url":733},"1787890622","https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Ffilefield_paths\u002Fissues\u002F3616606#comment-16749586",{"created":735,"url":736},"1787889464","https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Ffilefield_paths\u002Fissues\u002F3616606#comment-16749583",{"created":738,"url":739},"1787887387","https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Fdecoupled_settings\u002Fissues\u002F3619604#comment-16749580",{"created":741,"url":742},"1787886777","https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Fdecoupled_settings\u002Fissues\u002F3619603#comment-16749579",{"created":744,"url":745},"1787802107","https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Ffilefield_paths\u002Fissues\u002F3569210#comment-16748329",{"created":747,"url":748},"1787794815","https:\u002F\u002Fwww.drupal.org\u002Fproject\u002Ffilefield_paths\u002Fissues\u002F3569210#comment-16748309",{"list":750},[751,754,757,760,763,766,769,772,775,778,781,784,787,790,793,796,799,802,805,808,811,814,817,820,823,826,829,832,835,838,841,844,847,850,853,856,859,862,865,868,871,874,877,880,883,886,889,892,895,898],{"created":752,"title":753},"1790823068","filefield_paths 8.x-1.0",{"created":755,"title":756},"1788935723","druxt 1.3.1",{"created":758,"title":759},"1788925070","druxt 1.3.0",{"created":761,"title":762},"1788768644","druxt 1.3.x-dev",{"created":764,"title":765},"1788767562","filefield_paths 8.x-1.0-rc2",{"created":767,"title":768},"1788585516","druxt 1.2.2",{"created":770,"title":771},"1787731539","decoupled_settings 1.0.0-beta2",{"created":773,"title":774},"1787654460","decoupled_settings 1.0.0-beta1",{"created":776,"title":777},"1787382308","decoupled_router 2.0.7",{"created":779,"title":780},"1786266222","jsonapi_views 8.x-1.2",{"created":782,"title":783},"1785462039","custom_formatters 4.1.0",{"created":785,"title":786},"1784183539","imagefield_tokens 3.2.x-dev",{"created":788,"title":789},"1783477661","field_tokens 2.0.0",{"created":791,"title":792},"1781748605","field_tokens 2.0.0-rc4",{"created":794,"title":795},"1780823431","custom_formatters 4.1.0-beta3",{"created":797,"title":798},"1779757758","field_tokens 2.0.x-dev",{"created":800,"title":801},"1779586472","custom_formatters 4.1.0-beta2",{"created":803,"title":804},"1777794354","custom_formatters 4.1.x-dev",{"created":806,"title":807},"1676000321","druxt 1.2.x-dev",{"created":809,"title":810},"1676000291","druxt 1.2.0",{"created":812,"title":813},"1675998772","jsonapi_views 8.x-1.1",{"created":815,"title":816},"1635120605","druxt 1.1.1",{"created":818,"title":819},"1634962907","druxt 1.1.0",{"created":821,"title":822},"1634962672","druxt 1.1.x-dev",{"created":824,"title":825},"1633070672","jsonapi_views 8.x-1.0",{"created":827,"title":828},"1623905502","jsonapi_views 8.x-1.0-beta3",{"created":830,"title":831},"1623037306","druxt 1.0.2",{"created":833,"title":834},"1622617266","druxt 1.0.1",{"created":836,"title":837},"1619993261","jsonapi_menu_items 1.2.1",{"created":839,"title":840},"1619843589","druxt 1.0.0",{"created":842,"title":843},"1618724732","jsonapi_menu_items 1.2.0",{"created":845,"title":846},"1618724492","jsonapi_menu_items 1.2.x-dev",{"created":848,"title":849},"1616619130","jsonapi_views 8.x-1.0-beta2",{"created":851,"title":852},"1615111239","druxt 1.0.0-beta2",{"created":854,"title":855},"1612775511","druxt 1.0.0-beta1",{"created":857,"title":858},"1612768879","jsonapi_views 8.x-1.0-beta1",{"created":860,"title":861},"1611263472","jsonapi_menu_items 1.1.1",{"created":863,"title":864},"1611184889","jsonapi_menu_items 1.1.x-dev",{"created":866,"title":867},"1602805495","druxt 0.4.1",{"created":869,"title":870},"1600354700","jsonapi_menu_items 1.1.0",{"created":872,"title":873},"1599791532","jsonapi_menu_items 1.0.1",{"created":875,"title":876},"1599537629","druxt 0.4.0",{"created":878,"title":879},"1599199621","jsonapi_menu_items 1.0.0",{"created":881,"title":882},"1599199507","jsonapi_menu_items 1.0.x-dev",{"created":884,"title":885},"1598235135","druxt 0.3.0",{"created":887,"title":888},"1597270761","druxt 0.2.0",{"created":890,"title":891},"1597127254","decoupled_router 8.x-1.12",{"created":893,"title":894},"1595661841","druxt 0.1.0",{"created":896,"title":897},"1595661719","druxt 0.0.x-dev",{"created":899,"title":900},"1595067695","druxt 1.0.x-dev",[902,907,911,916,920,924,928,932,936,940,944,948,952,956,960,964,968,972,976,980,984,988,992,996,1000,1004,1008,1012,1016,1020,1024,1028,1032,1037,1041,1045,1049,1053,1057,1061,1065,1069,1073,1077,1081,1085,1089,1093,1097,1101,1105,1109,1113,1117,1121,1125,1129,1133,1137,1141,1145,1149,1153,1157,1161,1165,1169,1173,1177,1181,1185,1189,1193,1197],{"created_at":903,"state":904,"web_url":905,"title":906},"2026-10-01T02:14:00.174Z","merged","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Ffilefield_paths\u002F-\u002Fmerge_requests\u002F82","chore(release): prepare 8.x-1.0",{"created_at":908,"state":904,"web_url":909,"title":910},"2026-09-18T23:59:57.651Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Ffilefield_paths\u002F-\u002Fmerge_requests\u002F81","fix(#3277844): stage each upload in a directory of its own",{"created_at":912,"state":913,"web_url":914,"title":915},"2026-09-11T01:49:51.143Z","opened","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Fjsonapi_menu_items\u002F-\u002Fmerge_requests\u002F32","feat(#3591565): advertise the core Menu Linkset URL from menu_items responses",{"created_at":917,"state":904,"web_url":918,"title":919},"2026-09-07T07:59:09.857Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Fdruxt\u002F-\u002Fmerge_requests\u002F24","feat(#3309969): make the exposed JSON:API resource list configurable",{"created_at":921,"state":904,"web_url":922,"title":923},"2026-09-02T10:09:55.374Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Ffilefield_paths\u002F-\u002Fmerge_requests\u002F79","Issue #3045063: Change redirect hash to match the Redirect module",{"created_at":925,"state":904,"web_url":926,"title":927},"2026-08-28T06:23:23.488Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Ffilefield_paths\u002F-\u002Fmerge_requests\u002F77","test(#3432653): cover the migration path that reported the crash",{"created_at":929,"state":904,"web_url":930,"title":931},"2026-08-28T04:15:32.747Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Ffilefield_paths\u002F-\u002Fmerge_requests\u002F76","Issue #3616606: Detect the original entity without property_exists",{"created_at":933,"state":913,"web_url":934,"title":935},"2026-08-25T03:57:52.449Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Fjsonapi_node_preview\u002F-\u002Fmerge_requests\u002F4","Issue #3367724 by amermod, deciphered: Load included references from memory and by revision",{"created_at":937,"state":904,"web_url":938,"title":939},"2026-08-24T23:20:50.079Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Fdruxt\u002F-\u002Fmerge_requests\u002F23","fix(#3618677): guard the jsonapi_views route lookup in the Views subscriber",{"created_at":941,"state":913,"web_url":942,"title":943},"2026-08-24T07:25:42.420Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Ffilefield_paths\u002F-\u002Fmerge_requests\u002F75","fix(#3015137): point the field item at the moved file",{"created_at":945,"state":904,"web_url":946,"title":947},"2026-08-23T21:29:04.023Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Fdruxt\u002F-\u002Fmerge_requests\u002F22","fix(#3618675): restore Decoupled Router 2.0.7 compatibility",{"created_at":949,"state":913,"web_url":950,"title":951},"2026-08-22T07:29:02.073Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Fjsonapi_menu_items\u002F-\u002Fmerge_requests\u002F31","test(#3171186): add menu_link_config test coverage",{"created_at":953,"state":904,"web_url":954,"title":955},"2026-08-20T05:41:30.726Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Ftextimage\u002F-\u002Fmerge_requests\u002F27","ci: trigger GitHub workflows on the 5.0.x branch",{"created_at":957,"state":904,"web_url":958,"title":959},"2026-08-18T08:39:12.019Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Ffilefield_paths\u002F-\u002Fmerge_requests\u002F74","feat(#3419618): allow cross-scheme file moves and report skipped files during retroactive update",{"created_at":961,"state":904,"web_url":962,"title":963},"2026-08-17T04:33:52.709Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Fdecoupled_router\u002F-\u002Fmerge_requests\u002F40","fix(#3166364): replace dead path hooks with entity hooks",{"created_at":965,"state":904,"web_url":966,"title":967},"2026-08-14T00:46:24.947Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Ffilefield_paths\u002F-\u002Fmerge_requests\u002F73","fix: resolve phpstan and rector deprecation warnings",{"created_at":969,"state":904,"web_url":970,"title":971},"2026-08-14T00:45:46.775Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Fdecoupled_router\u002F-\u002Fmerge_requests\u002F39","ci: fix intermittent phpunit failures on the shared runner",{"created_at":973,"state":904,"web_url":974,"title":975},"2026-08-12T11:26:29.637Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Fdecoupled_router\u002F-\u002Fmerge_requests\u002F38","fix(#3611685): Catch RedirectLoopException in RedirectPathTranslatorSubscriber",{"created_at":977,"state":904,"web_url":978,"title":979},"2026-08-06T09:21:33.173Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Fjsonapi_views\u002F-\u002Fmerge_requests\u002F26","fix(#3265781): add resource type route default for single-bundle views",{"created_at":981,"state":904,"web_url":982,"title":983},"2026-08-04T01:45:14.605Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Fjsonapi_views\u002F-\u002Fmerge_requests\u002F25","Issue #3484714: Increase route build speed",{"created_at":985,"state":904,"web_url":986,"title":987},"2026-08-04T00:30:35.129Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Fjsonapi_views\u002F-\u002Fmerge_requests\u002F24","Issue #3202583: Views cache settings not added to headers",{"created_at":989,"state":904,"web_url":990,"title":991},"2026-07-29T10:44:55.917Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Fcustom_formatters\u002F-\u002Fmerge_requests\u002F13","fix: resolve pre-existing phpstan and phpcs CI failures",{"created_at":993,"state":904,"web_url":994,"title":995},"2026-07-25T00:28:19.398Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Fdruxt\u002F-\u002Fmerge_requests\u002F21","test: add comprehensive coverage for path translator subscribers",{"created_at":997,"state":904,"web_url":998,"title":999},"2026-07-23T03:39:56.630Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Fdruxt\u002F-\u002Fmerge_requests\u002F20","fix(#3597394): add Drupal 12 compatibility, drop D8\u002FD9",{"created_at":1001,"state":904,"web_url":1002,"title":1003},"2026-07-22T23:56:40.172Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Fdruxt\u002F-\u002Fmerge_requests\u002F19","fix(#3558380): pass route name string to Url::fromRoute in Views subscriber",{"created_at":1005,"state":904,"web_url":1006,"title":1007},"2026-07-21T02:14:34.763Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Fimagefield_tokens\u002F-\u002Fmerge_requests\u002F8","feat(#3452812): add widget settings for token-based default alt\u002Ftitle values",{"created_at":1009,"state":904,"web_url":1010,"title":1011},"2026-07-15T07:40:27.005Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Fimagefield_tokens\u002F-\u002Fmerge_requests\u002F7","fix(#3607919): full Drupal 11.4 compatibility and code modernization",{"created_at":1013,"state":913,"web_url":1014,"title":1015},"2026-07-06T05:10:08.723Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Ffilefield_paths\u002F-\u002Fmerge_requests\u002F71","feat(#3608361): pass field delta in token data for [file:delta] support",{"created_at":1017,"state":913,"web_url":1018,"title":1019},"2026-06-22T05:59:57.121Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Ffilefield_paths\u002F-\u002Fmerge_requests\u002F70","feat(#2072237): allow disabling File (Field) Paths processing site-wide and per entity",{"created_at":1021,"state":913,"web_url":1022,"title":1023},"2026-06-19T04:22:57.651Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Ffilefield_paths\u002F-\u002Fmerge_requests\u002F69","Draft: Test coverage: src\u002F, .module, and .install",{"created_at":1025,"state":904,"web_url":1026,"title":1027},"2026-06-19T01:26:51.661Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Ffilefield_paths\u002F-\u002Fmerge_requests\u002F68","test(#3269636): add failing test for private:\u002F\u002F redirect path bug",{"created_at":1029,"state":904,"web_url":1030,"title":1031},"2026-06-18T22:08:20.277Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Ffilefield_paths\u002F-\u002Fmerge_requests\u002F67","fix(#3121826): add on-demand image style delivery for temporary:\u002F\u002F staged files",{"created_at":1033,"state":1034,"web_url":1035,"title":1036},"2026-06-18T08:41:50.682Z","closed","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Ffilefield_paths\u002F-\u002Fmerge_requests\u002F66","Draft: feat: adopt drupal_extension_scaffold tooling and CI",{"created_at":1038,"state":904,"web_url":1039,"title":1040},"2026-05-31T07:36:44.683Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Ffield_tokens\u002F-\u002Fmerge_requests\u002F8","feat(#3267442): support ranges, wildcards, and omitted deltas in field tokens",{"created_at":1042,"state":913,"web_url":1043,"title":1044},"2026-05-31T02:19:43.604Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Fcustom_formatters\u002F-\u002Fmerge_requests\u002F11","Draft: ci: update scaffold, add GitLab CI, bump PHPStan to ^2, fix PHPStan 2.x errors",{"created_at":1046,"state":904,"web_url":1047,"title":1048},"2026-01-20T02:02:21.521Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Fdrupal_cms\u002F-\u002Fmerge_requests\u002F763","#3568407: remove obsolete automatic_updates_extensions from drupal_cms_admin_ui recipe",{"created_at":1050,"state":913,"web_url":1051,"title":1052},"2025-09-05T04:10:35.319Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Fnext\u002F-\u002Fmerge_requests\u002F4","feat(#3545030): add workspace id to preview query",{"created_at":1054,"state":904,"web_url":1055,"title":1056},"2025-08-17T23:57:03.628Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Fdruxt\u002F-\u002Fmerge_requests\u002F17","feat(#3541756): set default CORS allowedHeaders.",{"created_at":1058,"state":913,"web_url":1059,"title":1060},"2025-05-08T03:51:14.946Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Fadmin_audit_trail\u002F-\u002Fmerge_requests\u002F17","Draft: #3284680: added export csv route",{"created_at":1062,"state":1034,"web_url":1063,"title":1064},"2023-06-16T04:38:06.627Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Fsimple_oauth_revoke\u002F-\u002Fmerge_requests\u002F2","Issue #3367157: Add support for D10",{"created_at":1066,"state":913,"web_url":1067,"title":1068},"2023-02-27T00:01:54.487Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Fjsonapi_user_resources\u002F-\u002Fmerge_requests\u002F3","Issue #3288150: Automated Drupal 10 compatibility fixes",{"created_at":1070,"state":1034,"web_url":1071,"title":1072},"2023-02-09T00:41:07.583Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Fm4032404\u002F-\u002Fmerge_requests\u002F1","Issue #3288400: Automated Drupal 10 compatibility fixes",{"created_at":1074,"state":913,"web_url":1075,"title":1076},"2023-02-09T00:08:49.582Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Fentity_display_mode\u002F-\u002Fmerge_requests\u002F1","Issue #3287230: Automated Drupal 10 compatibility fixes",{"created_at":1078,"state":904,"web_url":1079,"title":1080},"2023-02-08T23:29:59.816Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Fanonymous_redirect\u002F-\u002Fmerge_requests\u002F1","Issue #3286076: Automated Drupal 10 compatibility fixes",{"created_at":1082,"state":1034,"web_url":1083,"title":1084},"2023-02-07T03:23:22.157Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Fparagraphs_ee\u002F-\u002Fmerge_requests\u002F14","Issue #3288984: Automated Drupal 10 compatibility fixes",{"created_at":1086,"state":1034,"web_url":1087,"title":1088},"2023-02-07T01:11:04.418Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Fdruxt\u002F-\u002Fmerge_requests\u002F12","Issue #3287092: Automated Drupal 10 compatibility fixes",{"created_at":1090,"state":904,"web_url":1091,"title":1092},"2023-02-07T00:46:55.790Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Fjsonapi_views\u002F-\u002Fmerge_requests\u002F9","Issue #3288151: Automated Drupal 10 compatibility fixes",{"created_at":1094,"state":904,"web_url":1095,"title":1096},"2022-10-12T23:02:59.783Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Fdruxt\u002F-\u002Fmerge_requests\u002F11","Issue #3315030: Add a wildcard route translator service to catch all available routes",{"created_at":1098,"state":904,"web_url":1099,"title":1100},"2022-10-12T22:48:23.867Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Fdruxt\u002F-\u002Fmerge_requests\u002F10","Issue #3315035: Cannot load the \"view\" entity with NULL ID",{"created_at":1102,"state":913,"web_url":1103,"title":1104},"2022-04-08T01:53:56.404Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Fjsonapi_menu_items\u002F-\u002Fmerge_requests\u002F7","Issue #3192576: Add langcode",{"created_at":1106,"state":913,"web_url":1107,"title":1108},"2022-04-08T00:42:54.086Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Fdecoupled_router\u002F-\u002Fmerge_requests\u002F5","Issue #3111456: Unable to resolve path on node in other language than default",{"created_at":1110,"state":913,"web_url":1111,"title":1112},"2022-04-06T04:09:03.877Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Fdruxt\u002F-\u002Fmerge_requests\u002F9","Issue #3273228: Add langcode to Views Decoupled Router integration",{"created_at":1114,"state":1034,"web_url":1115,"title":1116},"2022-03-22T03:37:58.299Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Felasticsearch_connector\u002F-\u002Fmerge_requests\u002F17","Issue #3186674: Support php 8",{"created_at":1118,"state":904,"web_url":1119,"title":1120},"2022-03-03T02:27:25.013Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Flinkit_media_library\u002F-\u002Fmerge_requests\u002F1","Issue #3267475: Add data-entity-bundle prop for better JSON:API support",{"created_at":1122,"state":904,"web_url":1123,"title":1124},"2022-02-26T00:23:00.535Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Fjsonapi_node_preview_tab\u002F-\u002Fmerge_requests\u002F2","Issue #3266416: create url from route",{"created_at":1126,"state":913,"web_url":1127,"title":1128},"2022-02-14T02:22:16.263Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Fdruxt\u002F-\u002Fmerge_requests\u002F8","Issue #3264181: Node Preview",{"created_at":1130,"state":1034,"web_url":1131,"title":1132},"2022-01-07T08:20:49.629Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Fdrupal\u002F-\u002Fmerge_requests\u002F1619","#3257163: Add bundle to drupal-media",{"created_at":1134,"state":904,"web_url":1135,"title":1136},"2021-11-15T21:19:32.592Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Fdruxt\u002F-\u002Fmerge_requests\u002F7","Issue #3249293: Error: Call to a member function isInternal() on null in \u002Fvar\u002Fwww\u002Fhtml\u002Fweb\u002Fmodules\u002Fcontrib\u002Fdruxt\u002Fdruxt.install on line 44",{"created_at":1138,"state":904,"web_url":1139,"title":1140},"2021-10-24T00:46:07.309Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Fdruxt\u002F-\u002Fmerge_requests\u002F6","Issue #3245544: Decoupled Views routes returning `null` label in Drupal 9.2",{"created_at":1142,"state":904,"web_url":1143,"title":1144},"2021-10-22T05:22:01.957Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Fdruxt\u002F-\u002Fmerge_requests\u002F5","Issue #3232542: Add Report for required JSON:API resources",{"created_at":1146,"state":904,"web_url":1147,"title":1148},"2021-10-20T05:53:01.933Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Fdruxt\u002F-\u002Fmerge_requests\u002F4","Issue #3206487: Add 'configurable_language' endpoint.",{"created_at":1150,"state":904,"web_url":1151,"title":1152},"2021-10-20T02:30:37.861Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Fdruxt\u002F-\u002Fmerge_requests\u002F3","Issue #3244770: Add access to 'jsonapi_resource_config--jsonapi_resource_config' endpoint",{"created_at":1154,"state":904,"web_url":1155,"title":1156},"2021-10-01T04:39:23.079Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Fjsonapi_views\u002F-\u002Fmerge_requests\u002F5","Issue #3145281: Allow user to decide whether to expose the view with JSONAPI",{"created_at":1158,"state":904,"web_url":1159,"title":1160},"2021-10-01T02:25:48.242Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Fjsonapi_views\u002F-\u002Fmerge_requests\u002F4","Issue #3239967: Pagination links are broken on Drupal 9.2.x",{"created_at":1162,"state":904,"web_url":1163,"title":1164},"2021-05-11T05:15:51.313Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Fjsonapi_menu_items\u002F-\u002Fmerge_requests\u002F5","Issue #3213317: No results for filters results in 403.",{"created_at":1166,"state":913,"web_url":1167,"title":1168},"2021-05-11T00:08:46.068Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Fjsonapi_menu_items\u002F-\u002Fmerge_requests\u002F4","Issue #3198306: Add link to related JSON:API resources.",{"created_at":1170,"state":904,"web_url":1171,"title":1172},"2021-05-02T06:11:17.311Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Fjsonapi_menu_items\u002F-\u002Fmerge_requests\u002F3","Issue #3211656: Caching issues with filters",{"created_at":1174,"state":904,"web_url":1175,"title":1176},"2021-05-01T02:17:45.922Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Fdruxt\u002F-\u002Fmerge_requests\u002F2","Issue #3211751: Missing EntityViewDisplays",{"created_at":1178,"state":913,"web_url":1179,"title":1180},"2021-04-17T02:05:22.149Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Fjsonapi_menu_items\u002F-\u002Fmerge_requests\u002F2","Issue #3171371: Add filters for menu tree parameters",{"created_at":1182,"state":904,"web_url":1183,"title":1184},"2021-04-14T10:51:45.107Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Fjsonapi_menu_items\u002F-\u002Fmerge_requests\u002F1","Issue #3205065: Menu items not discoverable",{"created_at":1186,"state":904,"web_url":1187,"title":1188},"2021-03-24T11:53:31.999Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Fjsonapi_views\u002F-\u002Fmerge_requests\u002F2","Issue #3205301: Add JSON:API Url to Query preview info.",{"created_at":1190,"state":904,"web_url":1191,"title":1192},"2021-03-07T04:09:31.707Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Fdruxt\u002F-\u002Fmerge_requests\u002F1","Issue #3202067: Expose 'menu--menu' resource attributes.",{"created_at":1194,"state":904,"web_url":1195,"title":1196},"2021-03-01T04:43:51.902Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Fjsonapi_views\u002F-\u002Fmerge_requests\u002F1","Issue #3200875: Error: Call to a member function getPagerId() on null",{"created_at":1198,"state":904,"web_url":1199,"title":1200},"2020-12-09T05:47:52.660Z","https:\u002F\u002Fgit.drupalcode.org\u002Fproject\u002Fdecoupled_router\u002F-\u002Fmerge_requests\u002F1","Issue #3187393: Linting fixes.",[1202,1210,1216,1223,1228,1234,1241,1247,1252,1257,1262,1267,1271,1275,1279,1284,1288,1293,1298,1303,1307,1312,1316,1321,1325,1329,1335,1340,1346,1351,1356,1360,1366,1373,1379,1384,1389,1394,1398,1402,1408,1413,1417,1421,1426,1431,1437,1442,1448,1454,1458,1463,1468,1474,1479,1483,1487,1492,1496,1500,1505,1509,1515,1520,1524,1529,1533,1537,1541,1547,1552,1555,1560,1566,1571,1576,1581,1585,1590,1595,1599,1604,1609,1613,1618,1623,1628,1632,1637,1642,1648,1653,1658,1662,1667,1671,1676,1680,1683,1687,1691,1697,1702,1708,1713,1719,1724,1728,1731,1737,1741,1745,1751,1756,1761,1766,1771,1775,1780,1784,1789,1794,1799,1804,1809,1814,1819,1824,1829,1833,1838,1842,1847,1852,1857,1862,1867,1871,1876,1881,1886,1891,1896,1901,1906,1910,1914,1919,1923,1927,1932,1936,1942,1946,1952,1958,1964,1969,1973,1980,1986,1992,1998,2003,2009,2015,2021,2027,2033,2039,2045,2051,2057,2062,2066,2070,2074,2079,2084,2089,2093,2098,2102,2107,2113,2118,2124,2129,2132,2135,2139,2143,2147,2152,2156,2159,2163,2167,2170,2173,2177,2181,2184,2187,2191,2194,2197,2200,2203,2207,2211,2214,2217,2221,2225,2229,2233,2237,2242,2246,2249,2252,2257,2261,2265,2269,2273,2277,2281,2284,2287,2290,2293,2296,2300,2304,2307,2311,2314,2317,2320,2323,2326,2329,2333,2336,2339,2345,2349,2354,2360,2364,2370,2374,2378,2382,2386,2391,2395,2399,2402,2405,2408,2412,2417,2422,2427,2431,2434,2437,2441,2445,2448,2451,2455,2459,2463,2467,2470,2473,2476,2480,2484,2488,2491,2494,2498,2501,2506,2510,2514,2517,2520,2523,2528,2532,2535,2539,2542,2545],{"type":1203,"repo":1204,"created_at":1206,"payload":1207},"PullRequestEvent",{"name":1205},"Decipher\u002Fstuar.tc","2026-10-02T02:40:55Z",{"action":904,"pull_request":1208},{"number":1209},203,{"type":1211,"repo":1212,"created_at":1213,"payload":1214},"PushEvent",{"name":1205},"2026-10-02T02:40:56Z",{"ref":1215},"refs\u002Fheads\u002Fmain",{"type":1203,"repo":1217,"created_at":1219,"payload":1220},{"name":1218},"druxt\u002Fdruxtjs.org","2026-10-02T02:33:42Z",{"action":913,"pull_request":1221},{"number":1222},103,{"type":1203,"repo":1224,"created_at":1225,"payload":1226},{"name":1205},"2026-10-02T02:30:55Z",{"action":913,"pull_request":1227},{"number":1209},{"type":1211,"repo":1229,"created_at":1231,"payload":1232},{"name":1230},"druxt\u002Fumami.demo.druxtjs.org","2026-10-01T23:48:57Z",{"ref":1233},"refs\u002Fheads\u002Ffeature\u002Ffrontend-cache",{"type":1235,"repo":1236,"created_at":1237,"payload":1238},"CreateEvent",{"name":1218},"2026-10-01T22:45:14Z",{"ref":1239,"ref_type":1240},"feature\u002Fllms-describedby","branch",{"type":1235,"repo":1242,"created_at":1244,"payload":1245},{"name":1243},"druxt\u002Fdruxt.js","2026-09-30T11:15:28Z",{"ref":1246,"ref_type":1240},"fix\u002Fclient-fallback-prefix",{"type":1235,"repo":1248,"created_at":1249,"payload":1250},{"name":1218},"2026-10-01T16:31:20Z",{"ref":1251,"ref_type":1240},"feature\u002Fga-referral-spam",{"type":1211,"repo":1253,"created_at":1254,"payload":1255},{"name":1218},"2026-10-01T16:43:59Z",{"ref":1256},"refs\u002Fheads\u002Ffeature\u002Fga-referral-spam",{"type":1211,"repo":1258,"created_at":1259,"payload":1260},{"name":1205},"2026-10-01T09:00:36Z",{"ref":1261},"refs\u002Fheads\u002Fdevelop",{"type":1211,"repo":1263,"created_at":1264,"payload":1265},{"name":1205},"2026-10-01T07:19:00Z",{"ref":1266},"refs\u002Fheads\u002Ffeat\u002Fllms-full-txt",{"type":1211,"repo":1268,"created_at":1269,"payload":1270},{"name":1205},"2026-10-01T07:16:09Z",{"ref":1266},{"type":1211,"repo":1272,"created_at":1273,"payload":1274},{"name":1230},"2026-09-30T08:01:40Z",{"ref":1233},{"type":1211,"repo":1276,"created_at":1277,"payload":1278},{"name":1205},"2026-10-01T07:26:43Z",{"ref":1266},{"type":1235,"repo":1280,"created_at":1281,"payload":1282},{"name":1205},"2026-10-01T07:05:40Z",{"ref":1283,"ref_type":1240},"feat\u002Fllms-full-txt",{"type":1211,"repo":1285,"created_at":1286,"payload":1287},{"name":1205},"2026-10-01T06:28:07Z",{"ref":1261},{"type":1211,"repo":1289,"created_at":1290,"payload":1291},{"name":1243},"2026-09-30T06:53:43Z",{"ref":1292},"refs\u002Fheads\u002Ffix\u002Fsession-cookie-patterns",{"type":1235,"repo":1294,"created_at":1295,"payload":1296},{"name":1205},"2026-10-01T06:19:30Z",{"ref":1297,"ref_type":1240},"chore\u002Frelease-v1.9.0",{"type":1211,"repo":1299,"created_at":1300,"payload":1301},{"name":1243},"2026-09-30T06:47:40Z",{"ref":1302},"refs\u002Fheads\u002Fperf\u002Fmenu-key-by-query",{"type":1211,"repo":1304,"created_at":1305,"payload":1306},{"name":1205},"2026-10-01T06:29:20Z",{"ref":1261},{"type":1235,"repo":1308,"created_at":1309,"payload":1310},{"name":1205},"2026-10-01T05:55:50Z",{"ref":1311,"ref_type":1240},"docs\u002Ffilefield-paths-8x-1-0-post",{"type":1211,"repo":1313,"created_at":1314,"payload":1315},{"name":1230},"2026-10-01T05:53:36Z",{"ref":1233},{"type":1211,"repo":1317,"created_at":1318,"payload":1319},{"name":1243},"2026-09-30T06:47:45Z",{"ref":1320},"refs\u002Fheads\u002Ffeature\u002Fno-cache-write-guarantee",{"type":1211,"repo":1322,"created_at":1323,"payload":1324},{"name":1205},"2026-10-01T09:17:12Z",{"ref":1261},{"type":1211,"repo":1326,"created_at":1327,"payload":1328},{"name":1205},"2026-10-01T09:16:52Z",{"ref":1215},{"type":1203,"repo":1330,"created_at":1331,"payload":1332},{"name":1205},"2026-10-01T09:16:51Z",{"action":904,"pull_request":1333},{"number":1334},202,{"type":1203,"repo":1336,"created_at":1337,"payload":1338},{"name":1205},"2026-10-01T09:01:58Z",{"action":913,"pull_request":1339},{"number":1334},{"type":1203,"repo":1341,"created_at":1342,"payload":1343},{"name":1205},"2026-10-01T09:00:35Z",{"action":904,"pull_request":1344},{"number":1345},201,{"type":1235,"repo":1347,"created_at":1348,"payload":1349},{"name":1205},"2026-10-01T08:12:11Z",{"ref":1350,"ref_type":1240},"chore\u002Frelease-v1.10.0",{"type":1203,"repo":1352,"created_at":1353,"payload":1354},{"name":1205},"2026-10-01T08:12:13Z",{"action":913,"pull_request":1355},{"number":1345},{"type":1211,"repo":1357,"created_at":1358,"payload":1359},{"name":1205},"2026-10-01T08:10:32Z",{"ref":1261},{"type":1203,"repo":1361,"created_at":1362,"payload":1363},{"name":1205},"2026-10-01T08:10:31Z",{"action":904,"pull_request":1364},{"number":1365},200,{"type":1367,"repo":1368,"created_at":1369,"payload":1370},"PullRequestReviewCommentEvent",{"name":1205},"2026-10-01T07:43:17Z",{"action":1371,"pull_request":1372},"created",{"number":1365},{"type":1374,"repo":1375,"created_at":1376,"payload":1377},"PullRequestReviewEvent",{"name":1205},"2026-10-01T07:43:19Z",{"action":1371,"pull_request":1378},{"number":1365},{"type":1367,"repo":1380,"created_at":1381,"payload":1382},{"name":1205},"2026-10-01T07:43:15Z",{"action":1371,"pull_request":1383},{"number":1365},{"type":1374,"repo":1385,"created_at":1386,"payload":1387},{"name":1205},"2026-10-01T07:43:16Z",{"action":1371,"pull_request":1388},{"number":1365},{"type":1367,"repo":1390,"created_at":1391,"payload":1392},{"name":1205},"2026-10-01T07:43:14Z",{"action":1371,"pull_request":1393},{"number":1365},{"type":1374,"repo":1395,"created_at":1381,"payload":1396},{"name":1205},{"action":1371,"pull_request":1397},{"number":1365},{"type":1211,"repo":1399,"created_at":1400,"payload":1401},{"name":1205},"2026-10-01T07:43:13Z",{"ref":1266},{"type":1403,"repo":1404,"created_at":1405,"payload":1406},"IssueCommentEvent",{"name":1205},"2026-10-01T07:23:35Z",{"action":1371,"issue":1407},{"number":1365},{"type":1211,"repo":1409,"created_at":1410,"payload":1411},{"name":1230},"2026-09-30T02:30:48Z",{"ref":1412},"refs\u002Fheads\u002Ffeature\u002Fdruxt-dev-channel",{"type":1211,"repo":1414,"created_at":1415,"payload":1416},{"name":1230},"2026-10-01T00:58:58Z",{"ref":1233},{"type":1211,"repo":1418,"created_at":1419,"payload":1420},{"name":1205},"2026-10-01T07:07:05Z",{"ref":1266},{"type":1403,"repo":1422,"created_at":1423,"payload":1424},{"name":1205},"2026-10-01T07:05:48Z",{"action":1371,"issue":1425},{"number":1365},{"type":1203,"repo":1427,"created_at":1428,"payload":1429},{"name":1205},"2026-10-01T07:05:41Z",{"action":913,"pull_request":1430},{"number":1365},{"type":1203,"repo":1432,"created_at":1433,"payload":1434},{"name":1205},"2026-10-01T06:28:06Z",{"action":904,"pull_request":1435},{"number":1436},197,{"type":1211,"repo":1438,"created_at":1440,"payload":1441},{"name":1439},"Decipher\u002Fdruxt.js","2026-09-30T01:49:55Z",{"ref":1215},{"type":1203,"repo":1443,"created_at":1444,"payload":1445},{"name":1205},"2026-10-01T06:17:20Z",{"action":904,"pull_request":1446},{"number":1447},196,{"type":1203,"repo":1449,"created_at":1450,"payload":1451},{"name":1205},"2026-10-01T06:29:04Z",{"action":904,"pull_request":1452},{"number":1453},198,{"type":1211,"repo":1455,"created_at":1456,"payload":1457},{"name":1205},"2026-10-01T06:29:05Z",{"ref":1215},{"type":1203,"repo":1459,"created_at":1460,"payload":1461},{"name":1205},"2026-10-01T06:28:51Z",{"action":913,"pull_request":1462},{"number":1453},{"type":1211,"repo":1464,"created_at":1465,"payload":1466},{"name":1230},"2026-09-30T00:31:13Z",{"ref":1467},"refs\u002Fheads\u002Ffeature\u002Fdruxt-module-1.3",{"type":1211,"repo":1469,"created_at":1471,"payload":1472},{"name":1470},"Decipher\u002Ffilefield_paths","2026-09-30T23:24:36Z",{"ref":1473},"refs\u002Fheads\u002F8.x-1.x",{"type":1203,"repo":1475,"created_at":1476,"payload":1477},{"name":1205},"2026-10-01T06:19:31Z",{"action":913,"pull_request":1478},{"number":1436},{"type":1211,"repo":1480,"created_at":1481,"payload":1482},{"name":1205},"2026-10-01T06:17:21Z",{"ref":1261},{"type":1211,"repo":1484,"created_at":1485,"payload":1486},{"name":1230},"2026-10-01T06:12:35Z",{"ref":1233},{"type":1211,"repo":1488,"created_at":1489,"payload":1490},{"name":1205},"2026-10-01T06:05:28Z",{"ref":1491},"refs\u002Fheads\u002Fdocs\u002Ffilefield-paths-8x-1-0-post",{"type":1211,"repo":1493,"created_at":1494,"payload":1495},{"name":1205},"2026-10-01T05:59:17Z",{"ref":1491},{"type":1211,"repo":1497,"created_at":1498,"payload":1499},{"name":1230},"2026-10-01T05:56:12Z",{"ref":1233},{"type":1203,"repo":1501,"created_at":1502,"payload":1503},{"name":1205},"2026-10-01T05:56:08Z",{"action":913,"pull_request":1504},{"number":1447},{"type":1211,"repo":1506,"created_at":1507,"payload":1508},{"name":1230},"2026-10-01T05:50:44Z",{"ref":1233},{"type":1510,"repo":1511,"created_at":1512,"payload":1513},"DeleteEvent",{"name":1470},"2026-09-30T23:24:58Z",{"ref":1514,"ref_type":1240},"feature\u002F3277844-multi-image-replace",{"type":1211,"repo":1516,"created_at":1517,"payload":1518},{"name":1230},"2026-09-30T23:05:23Z",{"ref":1519},"refs\u002Fheads\u002Ffeat\u002Fvisual-uplift",{"type":1211,"repo":1521,"created_at":1522,"payload":1523},{"name":1230},"2026-09-30T00:31:12Z",{"ref":1519},{"type":1211,"repo":1525,"created_at":1526,"payload":1527},{"name":1230},"2026-09-30T22:54:12Z",{"ref":1528},"refs\u002Fheads\u002Ffeat\u002Fdrupal-11",{"type":1211,"repo":1530,"created_at":1531,"payload":1532},{"name":1230},"2026-09-30T22:16:33Z",{"ref":1233},{"type":1211,"repo":1534,"created_at":1535,"payload":1536},{"name":1230},"2026-10-01T03:35:40Z",{"ref":1233},{"type":1211,"repo":1538,"created_at":1539,"payload":1540},{"name":1230},"2026-09-29T21:44:28Z",{"ref":1233},{"type":1203,"repo":1542,"created_at":1543,"payload":1544},{"name":1470},"2026-10-01T02:33:29Z",{"action":904,"pull_request":1545},{"number":1546},43,{"type":1510,"repo":1548,"created_at":1549,"payload":1550},{"name":1470},"2026-10-01T02:33:54Z",{"ref":1551,"ref_type":1240},"feature\u002F8.x-1.0-release-prep",{"type":1211,"repo":1553,"created_at":1543,"payload":1554},{"name":1470},{"ref":1473},{"type":1211,"repo":1556,"created_at":1557,"payload":1558},{"name":1470},"2026-10-01T02:08:40Z",{"ref":1559},"refs\u002Fheads\u002Ffeature\u002F8.x-1.0-release-prep",{"type":1367,"repo":1561,"created_at":1562,"payload":1563},{"name":1230},"2026-10-01T02:05:26Z",{"action":1371,"pull_request":1564},{"number":1565},498,{"type":1367,"repo":1567,"created_at":1568,"payload":1569},{"name":1230},"2026-10-01T02:05:19Z",{"action":1371,"pull_request":1570},{"number":1565},{"type":1367,"repo":1572,"created_at":1573,"payload":1574},{"name":1230},"2026-10-01T02:05:24Z",{"action":1371,"pull_request":1575},{"number":1565},{"type":1367,"repo":1577,"created_at":1578,"payload":1579},{"name":1230},"2026-10-01T02:05:17Z",{"action":1371,"pull_request":1580},{"number":1565},{"type":1211,"repo":1582,"created_at":1583,"payload":1584},{"name":1470},"2026-10-01T02:00:59Z",{"ref":1473},{"type":1374,"repo":1586,"created_at":1587,"payload":1588},{"name":1230},"2026-10-01T02:05:27Z",{"action":1371,"pull_request":1589},{"number":1565},{"type":1374,"repo":1591,"created_at":1592,"payload":1593},{"name":1230},"2026-10-01T02:05:25Z",{"action":1371,"pull_request":1594},{"number":1565},{"type":1374,"repo":1596,"created_at":1573,"payload":1597},{"name":1230},{"action":1371,"pull_request":1598},{"number":1565},{"type":1374,"repo":1600,"created_at":1601,"payload":1602},{"name":1230},"2026-10-01T02:05:23Z",{"action":1371,"pull_request":1603},{"number":1565},{"type":1367,"repo":1605,"created_at":1606,"payload":1607},{"name":1230},"2026-10-01T02:05:22Z",{"action":1371,"pull_request":1608},{"number":1565},{"type":1374,"repo":1610,"created_at":1568,"payload":1611},{"name":1230},{"action":1371,"pull_request":1612},{"number":1565},{"type":1367,"repo":1614,"created_at":1615,"payload":1616},{"name":1230},"2026-10-01T02:05:14Z",{"action":1371,"pull_request":1617},{"number":1565},{"type":1374,"repo":1619,"created_at":1620,"payload":1621},{"name":1230},"2026-10-01T02:05:15Z",{"action":1371,"pull_request":1622},{"number":1565},{"type":1367,"repo":1624,"created_at":1625,"payload":1626},{"name":1230},"2026-10-01T02:05:12Z",{"action":1371,"pull_request":1627},{"number":1565},{"type":1374,"repo":1629,"created_at":1625,"payload":1630},{"name":1230},{"action":1371,"pull_request":1631},{"number":1565},{"type":1211,"repo":1633,"created_at":1634,"payload":1635},{"name":1218},"2026-09-29T20:30:16Z",{"ref":1636},"refs\u002Fheads\u002Ffeature\u002Feditor-sign-in",{"type":1203,"repo":1638,"created_at":1639,"payload":1640},{"name":1470},"2026-10-01T02:02:07Z",{"action":913,"pull_request":1641},{"number":1546},{"type":1403,"repo":1643,"created_at":1644,"payload":1645},{"name":1470},"2026-10-01T02:01:15Z",{"action":1371,"issue":1646},{"number":1647},24,{"type":1203,"repo":1649,"created_at":1650,"payload":1651},{"name":1470},"2026-09-30T23:43:36Z",{"action":1034,"pull_request":1652},{"number":1647},{"type":1510,"repo":1654,"created_at":1655,"payload":1656},{"name":1470},"2026-10-01T02:01:18Z",{"ref":1657,"ref_type":1240},"feature\u002F3494240-staging-redirect",{"type":1211,"repo":1659,"created_at":1660,"payload":1661},{"name":1230},"2026-09-29T20:16:49Z",{"ref":1519},{"type":1211,"repo":1663,"created_at":1664,"payload":1665},{"name":1218},"2026-09-29T20:30:24Z",{"ref":1666},"refs\u002Fheads\u002Ffeature\u002Feditor-bar-polish",{"type":1211,"repo":1668,"created_at":1669,"payload":1670},{"name":1230},"2026-09-30T23:59:31Z",{"ref":1233},{"type":1211,"repo":1672,"created_at":1673,"payload":1674},{"name":1230},"2026-09-29T20:16:48Z",{"ref":1675},"refs\u002Fheads\u002Ffeature\u002Fsingle-environment",{"type":1211,"repo":1677,"created_at":1678,"payload":1679},{"name":1230},"2026-09-30T22:51:57Z",{"ref":1519},{"type":1211,"repo":1681,"created_at":1678,"payload":1682},{"name":1230},{"ref":1528},{"type":1211,"repo":1684,"created_at":1685,"payload":1686},{"name":1230},"2026-09-30T23:04:15Z",{"ref":1675},{"type":1211,"repo":1688,"created_at":1689,"payload":1690},{"name":1230},"2026-09-30T22:23:44Z",{"ref":1233},{"type":1203,"repo":1692,"created_at":1693,"payload":1694},{"name":1470},"2026-09-19T00:46:07Z",{"action":1034,"pull_request":1695},{"number":1696},31,{"type":1403,"repo":1698,"created_at":1699,"payload":1700},{"name":1470},"2026-09-30T23:24:56Z",{"action":1371,"issue":1701},{"number":1696},{"type":1203,"repo":1703,"created_at":1704,"payload":1705},{"name":1230},"2026-09-30T22:52:06Z",{"action":1034,"pull_request":1706},{"number":1707},504,{"type":1403,"repo":1709,"created_at":1710,"payload":1711},{"name":1230},"2026-09-30T23:10:47Z",{"action":1371,"issue":1712},{"number":1707},{"type":1203,"repo":1714,"created_at":1715,"payload":1716},{"name":1230},"2026-09-30T23:05:24Z",{"action":1034,"pull_request":1717},{"number":1718},503,{"type":1403,"repo":1720,"created_at":1721,"payload":1722},{"name":1230},"2026-09-30T23:10:44Z",{"action":1371,"issue":1723},{"number":1718},{"type":1211,"repo":1725,"created_at":1726,"payload":1727},{"name":1230},"2026-09-30T23:03:52Z",{"ref":1528},{"type":1211,"repo":1729,"created_at":1678,"payload":1730},{"name":1230},{"ref":1467},{"type":1203,"repo":1732,"created_at":1733,"payload":1734},{"name":1230},"2026-09-30T22:51:51Z",{"action":904,"pull_request":1735},{"number":1736},507,{"type":1211,"repo":1738,"created_at":1739,"payload":1740},{"name":1218},"2026-09-29T20:35:18Z",{"ref":1666},{"type":1211,"repo":1742,"created_at":1743,"payload":1744},{"name":1230},"2026-09-30T22:36:53Z",{"ref":1519},{"type":1367,"repo":1746,"created_at":1747,"payload":1748},{"name":1230},"2026-09-30T22:30:37Z",{"action":1371,"pull_request":1749},{"number":1750},502,{"type":1374,"repo":1752,"created_at":1753,"payload":1754},{"name":1230},"2026-09-30T22:30:38Z",{"action":1371,"pull_request":1755},{"number":1750},{"type":1367,"repo":1757,"created_at":1758,"payload":1759},{"name":1230},"2026-09-30T22:30:35Z",{"action":1371,"pull_request":1760},{"number":1565},{"type":1374,"repo":1762,"created_at":1763,"payload":1764},{"name":1230},"2026-09-30T22:30:36Z",{"action":1371,"pull_request":1765},{"number":1565},{"type":1367,"repo":1767,"created_at":1768,"payload":1769},{"name":1230},"2026-09-30T22:30:34Z",{"action":1371,"pull_request":1770},{"number":1565},{"type":1374,"repo":1772,"created_at":1768,"payload":1773},{"name":1230},{"action":1371,"pull_request":1774},{"number":1565},{"type":1367,"repo":1776,"created_at":1777,"payload":1778},{"name":1230},"2026-09-30T22:30:33Z",{"action":1371,"pull_request":1779},{"number":1565},{"type":1374,"repo":1781,"created_at":1777,"payload":1782},{"name":1230},{"action":1371,"pull_request":1783},{"number":1565},{"type":1367,"repo":1785,"created_at":1786,"payload":1787},{"name":1230},"2026-09-30T22:30:30Z",{"action":1371,"pull_request":1788},{"number":1565},{"type":1374,"repo":1790,"created_at":1791,"payload":1792},{"name":1230},"2026-09-30T22:30:31Z",{"action":1371,"pull_request":1793},{"number":1565},{"type":1367,"repo":1795,"created_at":1796,"payload":1797},{"name":1230},"2026-09-30T22:30:27Z",{"action":1371,"pull_request":1798},{"number":1565},{"type":1374,"repo":1800,"created_at":1801,"payload":1802},{"name":1230},"2026-09-30T22:30:28Z",{"action":1371,"pull_request":1803},{"number":1565},{"type":1367,"repo":1805,"created_at":1806,"payload":1807},{"name":1230},"2026-09-30T22:30:25Z",{"action":1371,"pull_request":1808},{"number":1565},{"type":1374,"repo":1810,"created_at":1811,"payload":1812},{"name":1230},"2026-09-30T22:30:26Z",{"action":1371,"pull_request":1813},{"number":1565},{"type":1367,"repo":1815,"created_at":1816,"payload":1817},{"name":1230},"2026-09-30T22:30:23Z",{"action":1371,"pull_request":1818},{"number":1565},{"type":1374,"repo":1820,"created_at":1821,"payload":1822},{"name":1230},"2026-09-30T22:30:24Z",{"action":1371,"pull_request":1823},{"number":1565},{"type":1367,"repo":1825,"created_at":1826,"payload":1827},{"name":1230},"2026-09-30T22:30:22Z",{"action":1371,"pull_request":1828},{"number":1565},{"type":1374,"repo":1830,"created_at":1816,"payload":1831},{"name":1230},{"action":1371,"pull_request":1832},{"number":1565},{"type":1367,"repo":1834,"created_at":1835,"payload":1836},{"name":1230},"2026-09-30T22:30:21Z",{"action":1371,"pull_request":1837},{"number":1565},{"type":1374,"repo":1839,"created_at":1835,"payload":1840},{"name":1230},{"action":1371,"pull_request":1841},{"number":1565},{"type":1367,"repo":1843,"created_at":1844,"payload":1845},{"name":1230},"2026-09-30T22:30:19Z",{"action":1371,"pull_request":1846},{"number":1565},{"type":1374,"repo":1848,"created_at":1849,"payload":1850},{"name":1230},"2026-09-30T22:30:20Z",{"action":1371,"pull_request":1851},{"number":1565},{"type":1367,"repo":1853,"created_at":1854,"payload":1855},{"name":1230},"2026-09-30T22:30:17Z",{"action":1371,"pull_request":1856},{"number":1565},{"type":1374,"repo":1858,"created_at":1859,"payload":1860},{"name":1230},"2026-09-30T22:30:18Z",{"action":1371,"pull_request":1861},{"number":1565},{"type":1367,"repo":1863,"created_at":1864,"payload":1865},{"name":1230},"2026-09-30T22:30:15Z",{"action":1371,"pull_request":1866},{"number":1565},{"type":1374,"repo":1868,"created_at":1864,"payload":1869},{"name":1230},{"action":1371,"pull_request":1870},{"number":1565},{"type":1367,"repo":1872,"created_at":1873,"payload":1874},{"name":1230},"2026-09-30T22:30:13Z",{"action":1371,"pull_request":1875},{"number":1565},{"type":1374,"repo":1877,"created_at":1878,"payload":1879},{"name":1230},"2026-09-30T22:30:14Z",{"action":1371,"pull_request":1880},{"number":1565},{"type":1367,"repo":1882,"created_at":1883,"payload":1884},{"name":1230},"2026-09-30T22:30:10Z",{"action":1371,"pull_request":1885},{"number":1565},{"type":1374,"repo":1887,"created_at":1888,"payload":1889},{"name":1230},"2026-09-30T22:30:11Z",{"action":1371,"pull_request":1890},{"number":1565},{"type":1367,"repo":1892,"created_at":1893,"payload":1894},{"name":1230},"2026-09-30T22:30:08Z",{"action":1371,"pull_request":1895},{"number":1565},{"type":1374,"repo":1897,"created_at":1898,"payload":1899},{"name":1230},"2026-09-30T22:30:09Z",{"action":1371,"pull_request":1900},{"number":1565},{"type":1367,"repo":1902,"created_at":1903,"payload":1904},{"name":1230},"2026-09-30T22:30:06Z",{"action":1371,"pull_request":1905},{"number":1565},{"type":1374,"repo":1907,"created_at":1903,"payload":1908},{"name":1230},{"action":1371,"pull_request":1909},{"number":1565},{"type":1211,"repo":1911,"created_at":1912,"payload":1913},{"name":1230},"2026-09-30T22:29:44Z",{"ref":1528},{"type":1403,"repo":1915,"created_at":1916,"payload":1917},{"name":1230},"2026-09-30T21:55:00Z",{"action":1371,"issue":1918},{"number":1736},{"type":1211,"repo":1920,"created_at":1921,"payload":1922},{"name":1230},"2026-09-30T11:40:53Z",{"ref":1233},{"type":1211,"repo":1924,"created_at":1925,"payload":1926},{"name":1230},"2026-09-30T10:58:40Z",{"ref":1233},{"type":1235,"repo":1928,"created_at":1929,"payload":1930},{"name":1243},"2026-09-30T10:47:14Z",{"ref":1931,"ref_type":1240},"fix\u002Fblocks-content-store-guard",{"type":1211,"repo":1933,"created_at":1934,"payload":1935},{"name":1230},"2026-09-30T10:18:58Z",{"ref":1233},{"type":1203,"repo":1937,"created_at":1938,"payload":1939},{"name":1243},"2026-09-30T11:15:38Z",{"action":913,"pull_request":1940},{"number":1941},894,{"type":1211,"repo":1943,"created_at":1944,"payload":1945},{"name":1230},"2026-09-30T07:35:13Z",{"ref":1233},{"type":1947,"repo":1948,"created_at":1950,"payload":1951},"PublicEvent",{"name":1949},"druxt-contrib\u002Fdruxt-ckeditor","2026-09-30T06:25:06Z",{},{"type":1203,"repo":1953,"created_at":1954,"payload":1955},{"name":1243},"2026-09-30T10:47:21Z",{"action":913,"pull_request":1956},{"number":1957},893,{"type":1203,"repo":1959,"created_at":1960,"payload":1961},{"name":1243},"2026-09-30T10:17:57Z",{"action":913,"pull_request":1962},{"number":1963},892,{"type":1403,"repo":1965,"created_at":1966,"payload":1967},{"name":1243},"2026-09-30T07:24:56Z",{"action":1371,"issue":1968},{"number":554},{"type":1211,"repo":1970,"created_at":1971,"payload":1972},{"name":1243},"2026-09-30T06:53:38Z",{"ref":1302},{"type":1974,"repo":1975,"created_at":1976,"payload":1977},"IssuesEvent",{"name":1218},"2026-09-30T09:45:41Z",{"action":913,"issue":1978},{"number":1979},101,{"type":1974,"repo":1981,"created_at":1982,"payload":1983},{"name":1218},"2026-09-30T09:45:30Z",{"action":913,"issue":1984},{"number":1985},96,{"type":1403,"repo":1987,"created_at":1988,"payload":1989},{"name":1243},"2026-09-30T07:24:15Z",{"action":1371,"issue":1990},{"number":1991},156,{"type":1974,"repo":1993,"created_at":1994,"payload":1995},{"name":1218},"2026-09-30T09:45:20Z",{"action":913,"issue":1996},{"number":1997},94,{"type":1403,"repo":1999,"created_at":2000,"payload":2001},{"name":1243},"2026-09-30T07:24:35Z",{"action":1371,"issue":2002},{"number":477},{"type":1403,"repo":2004,"created_at":2005,"payload":2006},{"name":1243},"2026-09-30T07:23:33Z",{"action":1371,"issue":2007},{"number":2008},70,{"type":1403,"repo":2010,"created_at":2011,"payload":2012},{"name":1243},"2026-09-30T07:22:28Z",{"action":1371,"issue":2013},{"number":2014},533,{"type":1403,"repo":2016,"created_at":2017,"payload":2018},{"name":1243},"2026-09-30T07:23:00Z",{"action":1371,"issue":2019},{"number":2020},546,{"type":1974,"repo":2022,"created_at":2023,"payload":2024},{"name":1218},"2026-09-30T09:30:31Z",{"action":913,"issue":2025},{"number":2026},100,{"type":1974,"repo":2028,"created_at":2029,"payload":2030},{"name":1218},"2026-09-30T09:30:24Z",{"action":913,"issue":2031},{"number":2032},98,{"type":1403,"repo":2034,"created_at":2035,"payload":2036},{"name":1243},"2026-09-30T07:22:04Z",{"action":1371,"issue":2037},{"number":2038},162,{"type":1974,"repo":2040,"created_at":2041,"payload":2042},{"name":1218},"2026-09-30T09:20:38Z",{"action":913,"issue":2043},{"number":2044},97,{"type":1367,"repo":2046,"created_at":2047,"payload":2048},{"name":1243},"2026-09-30T06:48:28Z",{"action":1371,"pull_request":2049},{"number":2050},886,{"type":1974,"repo":2052,"created_at":2053,"payload":2054},{"name":1218},"2026-09-30T08:41:35Z",{"action":913,"issue":2055},{"number":2056},95,{"type":1235,"repo":2058,"created_at":2059,"payload":2060},{"name":1243},"2026-09-30T08:15:36Z",{"ref":2061,"ref_type":1240},"feature\u002Fmenu-plugin-proxy",{"type":1211,"repo":2063,"created_at":2064,"payload":2065},{"name":1230},"2026-09-30T03:32:07Z",{"ref":1233},{"type":1211,"repo":2067,"created_at":2068,"payload":2069},{"name":1243},"2026-09-30T06:47:42Z",{"ref":1292},{"type":1211,"repo":2071,"created_at":2072,"payload":2073},{"name":1243},"2026-09-30T06:53:46Z",{"ref":1320},{"type":1974,"repo":2075,"created_at":2076,"payload":2077},{"name":1243},"2026-09-30T07:24:58Z",{"action":1034,"issue":2078},{"number":554},{"type":1974,"repo":2080,"created_at":2081,"payload":2082},{"name":1243},"2026-09-30T07:24:40Z",{"action":1034,"issue":2083},{"number":477},{"type":1974,"repo":2085,"created_at":2086,"payload":2087},{"name":1243},"2026-09-30T07:24:23Z",{"action":1034,"issue":2088},{"number":1991},{"type":1974,"repo":2090,"created_at":2005,"payload":2091},{"name":1243},{"action":1034,"issue":2092},{"number":2008},{"type":1974,"repo":2094,"created_at":2095,"payload":2096},{"name":1243},"2026-09-30T07:23:06Z",{"action":1034,"issue":2097},{"number":2020},{"type":1974,"repo":2099,"created_at":2011,"payload":2100},{"name":1243},{"action":1034,"issue":2101},{"number":2014},{"type":1974,"repo":2103,"created_at":2104,"payload":2105},{"name":1243},"2026-09-30T07:22:09Z",{"action":1034,"issue":2106},{"number":2038},{"type":1203,"repo":2108,"created_at":2109,"payload":2110},{"name":1243},"2026-09-30T07:04:08Z",{"action":913,"pull_request":2111},{"number":2112},891,{"type":1235,"repo":2114,"created_at":2115,"payload":2116},{"name":1243},"2026-09-30T07:02:45Z",{"ref":2117,"ref_type":1240},"feature\u002Fexports-package-json",{"type":1203,"repo":2119,"created_at":2120,"payload":2121},{"name":1243},"2026-09-30T06:48:46Z",{"action":2122,"pull_request":2123},"labeled",{"number":2050},{"type":1374,"repo":2125,"created_at":2126,"payload":2127},{"name":1243},"2026-09-30T06:48:29Z",{"action":1371,"pull_request":2128},{"number":2050},{"type":1211,"repo":2130,"created_at":1440,"payload":2131},{"name":1439},{"ref":1261},{"type":1211,"repo":2133,"created_at":1410,"payload":2134},{"name":1230},{"ref":1519},{"type":1211,"repo":2136,"created_at":2137,"payload":2138},{"name":1230},"2026-09-29T23:16:41Z",{"ref":1233},{"type":1211,"repo":2140,"created_at":2141,"payload":2142},{"name":1230},"2026-09-30T04:31:24Z",{"ref":1233},{"type":1211,"repo":2144,"created_at":2145,"payload":2146},{"name":1230},"2026-09-30T03:23:31Z",{"ref":1233},{"type":1211,"repo":2148,"created_at":2149,"payload":2150},{"name":1218},"2026-09-29T20:34:53Z",{"ref":2151},"refs\u002Fheads\u002Ffeature\u002Feditor-sign-in-base",{"type":1211,"repo":2153,"created_at":2154,"payload":2155},{"name":1230},"2026-09-29T20:59:22Z",{"ref":1467},{"type":1211,"repo":2157,"created_at":1410,"payload":2158},{"name":1230},{"ref":1467},{"type":1211,"repo":2160,"created_at":2161,"payload":2162},{"name":1218},"2026-09-29T20:30:00Z",{"ref":2151},{"type":1211,"repo":2164,"created_at":2165,"payload":2166},{"name":1218},"2026-09-29T20:35:09Z",{"ref":1636},{"type":1211,"repo":2168,"created_at":1673,"payload":2169},{"name":1230},{"ref":1467},{"type":1211,"repo":2171,"created_at":1410,"payload":2172},{"name":1230},{"ref":1233},{"type":1211,"repo":2174,"created_at":2175,"payload":2176},{"name":1230},"2026-09-29T02:31:20Z",{"ref":1233},{"type":1211,"repo":2178,"created_at":2179,"payload":2180},{"name":1230},"2026-09-29T02:27:37Z",{"ref":1528},{"type":1211,"repo":2182,"created_at":1465,"payload":2183},{"name":1230},{"ref":1233},{"type":1211,"repo":2185,"created_at":1465,"payload":2186},{"name":1230},{"ref":1412},{"type":1211,"repo":2188,"created_at":2189,"payload":2190},{"name":1230},"2026-09-29T01:42:56Z",{"ref":1233},{"type":1211,"repo":2192,"created_at":2137,"payload":2193},{"name":1230},{"ref":1519},{"type":1211,"repo":2195,"created_at":2137,"payload":2196},{"name":1230},{"ref":1467},{"type":1211,"repo":2198,"created_at":2137,"payload":2199},{"name":1230},{"ref":1412},{"type":1211,"repo":2201,"created_at":1539,"payload":2202},{"name":1230},{"ref":1519},{"type":1211,"repo":2204,"created_at":2205,"payload":2206},{"name":1230},"2026-09-29T02:27:36Z",{"ref":1467},{"type":1211,"repo":2208,"created_at":2209,"payload":2210},{"name":1230},"2026-09-29T20:59:23Z",{"ref":1412},{"type":1211,"repo":2212,"created_at":2154,"payload":2213},{"name":1230},{"ref":1233},{"type":1211,"repo":2215,"created_at":1539,"payload":2216},{"name":1230},{"ref":1412},{"type":1211,"repo":2218,"created_at":2219,"payload":2220},{"name":1230},"2026-09-29T21:44:27Z",{"ref":1467},{"type":1235,"repo":2222,"created_at":2209,"payload":2223},{"name":1230},{"ref":2224,"ref_type":1240},"feature\u002Fvisual-uplift",{"type":1211,"repo":2226,"created_at":2227,"payload":2228},{"name":1230},"2026-09-29T01:42:55Z",{"ref":1467},{"type":1211,"repo":2230,"created_at":2231,"payload":2232},{"name":1230},"2026-09-29T21:01:23Z",{"ref":1519},{"type":1211,"repo":2234,"created_at":2235,"payload":2236},{"name":1218},"2026-09-28T22:09:12Z",{"ref":2151},{"type":1211,"repo":2238,"created_at":2239,"payload":2240},{"name":1218},"2026-09-29T20:35:00Z",{"ref":2241},"refs\u002Fheads\u002Ffeature\u002Feditor-revisions",{"type":1211,"repo":2243,"created_at":2244,"payload":2245},{"name":1218},"2026-09-29T20:30:07Z",{"ref":2241},{"type":1211,"repo":2247,"created_at":1660,"payload":2248},{"name":1230},{"ref":1233},{"type":1211,"repo":2250,"created_at":1660,"payload":2251},{"name":1230},{"ref":1412},{"type":1211,"repo":2253,"created_at":2254,"payload":2255},{"name":1205},"2026-09-28T21:55:31Z",{"ref":2256},"refs\u002Fheads\u002Ffix\u002Fpreview-must-not-publish-production",{"type":1211,"repo":2258,"created_at":2259,"payload":2260},{"name":1218},"2026-09-28T22:43:28Z",{"ref":1666},{"type":1211,"repo":2262,"created_at":2263,"payload":2264},{"name":1218},"2026-09-28T22:43:14Z",{"ref":2241},{"type":1211,"repo":2266,"created_at":2267,"payload":2268},{"name":1230},"2026-09-28T22:04:03Z",{"ref":1528},{"type":1211,"repo":2270,"created_at":2271,"payload":2272},{"name":1230},"2026-09-28T15:22:39Z",{"ref":1519},{"type":1211,"repo":2274,"created_at":2275,"payload":2276},{"name":1230},"2026-09-29T02:33:59Z",{"ref":1467},{"type":1211,"repo":2278,"created_at":2279,"payload":2280},{"name":1230},"2026-09-29T02:33:58Z",{"ref":1233},{"type":1211,"repo":2282,"created_at":2175,"payload":2283},{"name":1230},{"ref":1675},{"type":1211,"repo":2285,"created_at":2205,"payload":2286},{"name":1230},{"ref":1233},{"type":1211,"repo":2288,"created_at":2179,"payload":2289},{"name":1230},{"ref":1675},{"type":1211,"repo":2291,"created_at":2227,"payload":2292},{"name":1230},{"ref":1412},{"type":1211,"repo":2294,"created_at":2227,"payload":2295},{"name":1230},{"ref":1519},{"type":1211,"repo":2297,"created_at":2298,"payload":2299},{"name":1230},"2026-09-28T15:22:40Z",{"ref":1528},{"type":1211,"repo":2301,"created_at":2302,"payload":2303},{"name":1218},"2026-09-28T22:09:26Z",{"ref":1636},{"type":1211,"repo":2305,"created_at":2302,"payload":2306},{"name":1218},{"ref":1636},{"type":1211,"repo":2308,"created_at":2309,"payload":2310},{"name":1230},"2026-09-28T22:04:04Z",{"ref":1519},{"type":1211,"repo":2312,"created_at":2309,"payload":2313},{"name":1230},{"ref":1467},{"type":1211,"repo":2315,"created_at":2275,"payload":2316},{"name":1230},{"ref":1519},{"type":1211,"repo":2318,"created_at":2279,"payload":2319},{"name":1230},{"ref":1412},{"type":1211,"repo":2321,"created_at":2175,"payload":2322},{"name":1230},{"ref":1412},{"type":1211,"repo":2324,"created_at":2175,"payload":2325},{"name":1230},{"ref":1519},{"type":1211,"repo":2327,"created_at":2175,"payload":2328},{"name":1230},{"ref":1528},{"type":1211,"repo":2330,"created_at":2331,"payload":2332},{"name":1230},"2026-09-29T02:31:19Z",{"ref":1467},{"type":1211,"repo":2334,"created_at":2205,"payload":2335},{"name":1230},{"ref":1519},{"type":1211,"repo":2337,"created_at":2205,"payload":2338},{"name":1230},{"ref":1412},{"type":1203,"repo":2340,"created_at":2341,"payload":2342},{"name":1205},"2026-09-29T01:53:38Z",{"action":904,"pull_request":2343},{"number":2344},195,{"type":1211,"repo":2346,"created_at":2347,"payload":2348},{"name":1205},"2026-09-29T01:53:39Z",{"ref":1261},{"type":1203,"repo":2350,"created_at":2351,"payload":2352},{"name":1205},"2026-09-29T01:31:41Z",{"action":913,"pull_request":2353},{"number":2344},{"type":1203,"repo":2355,"created_at":2356,"payload":2357},{"name":1205},"2026-09-29T01:29:54Z",{"action":904,"pull_request":2358},{"number":2359},193,{"type":1211,"repo":2361,"created_at":2362,"payload":2363},{"name":1205},"2026-09-29T01:29:56Z",{"ref":1261},{"type":1203,"repo":2365,"created_at":2366,"payload":2367},{"name":1205},"2026-09-29T01:28:51Z",{"action":904,"pull_request":2368},{"number":2369},194,{"type":1211,"repo":2371,"created_at":2372,"payload":2373},{"name":1205},"2026-09-29T01:28:52Z",{"ref":1215},{"type":1211,"repo":2375,"created_at":2376,"payload":2377},{"name":1230},"2026-09-28T11:04:02Z",{"ref":1467},{"type":1211,"repo":2379,"created_at":2380,"payload":2381},{"name":1218},"2026-09-28T22:43:22Z",{"ref":1636},{"type":1211,"repo":2383,"created_at":2384,"payload":2385},{"name":1218},"2026-09-28T22:43:07Z",{"ref":2151},{"type":1235,"repo":2387,"created_at":2388,"payload":2389},{"name":1230},"2026-09-28T10:12:28Z",{"ref":2390,"ref_type":1240},"feature\u002Fdruxt-dev-channel",{"type":1211,"repo":2392,"created_at":2393,"payload":2394},{"name":1218},"2026-09-28T22:09:31Z",{"ref":1666},{"type":1211,"repo":2396,"created_at":2397,"payload":2398},{"name":1218},"2026-09-28T22:09:19Z",{"ref":2241},{"type":1211,"repo":2400,"created_at":2309,"payload":2401},{"name":1230},{"ref":1233},{"type":1211,"repo":2403,"created_at":2309,"payload":2404},{"name":1230},{"ref":1675},{"type":1211,"repo":2406,"created_at":2267,"payload":2407},{"name":1230},{"ref":1412},{"type":1211,"repo":2409,"created_at":2410,"payload":2411},{"name":1205},"2026-09-28T21:58:12Z",{"ref":2256},{"type":1203,"repo":2413,"created_at":2414,"payload":2415},{"name":1205},"2026-09-28T21:50:47Z",{"action":913,"pull_request":2416},{"number":2369},{"type":1235,"repo":2418,"created_at":2419,"payload":2420},{"name":1205},"2026-09-28T21:50:20Z",{"ref":2421,"ref_type":1240},"fix\u002Fpreview-must-not-publish-production",{"type":1211,"repo":2423,"created_at":2424,"payload":2425},{"name":1218},"2026-09-28T08:40:41Z",{"ref":2426},"refs\u002Fheads\u002Ffeature\u002Fjsonapi-cache-config",{"type":1211,"repo":2428,"created_at":2429,"payload":2430},{"name":1218},"2026-09-28T08:38:25Z",{"ref":1666},{"type":1211,"repo":2432,"created_at":2298,"payload":2433},{"name":1230},{"ref":1233},{"type":1211,"repo":2435,"created_at":2298,"payload":2436},{"name":1230},{"ref":1467},{"type":1211,"repo":2438,"created_at":2271,"payload":2439},{"name":1230},{"ref":2440},"refs\u002Fheads\u002Ffeature\u002Frepo-standards",{"type":1211,"repo":2442,"created_at":2443,"payload":2444},{"name":1218},"2026-09-28T17:38:38Z",{"ref":2426},{"type":1211,"repo":2446,"created_at":2271,"payload":2447},{"name":1230},{"ref":1412},{"type":1211,"repo":2449,"created_at":2271,"payload":2450},{"name":1230},{"ref":1675},{"type":1211,"repo":2452,"created_at":2453,"payload":2454},{"name":1243},"2026-09-28T06:14:36Z",{"ref":1292},{"type":1211,"repo":2456,"created_at":2457,"payload":2458},{"name":1243},"2026-09-28T06:14:34Z",{"ref":1261},{"type":1211,"repo":2460,"created_at":2461,"payload":2462},{"name":1230},"2026-09-28T11:24:34Z",{"ref":1519},{"type":1211,"repo":2464,"created_at":2465,"payload":2466},{"name":1230},"2026-09-28T11:06:30Z",{"ref":1467},{"type":1211,"repo":2468,"created_at":2465,"payload":2469},{"name":1230},{"ref":1233},{"type":1211,"repo":2471,"created_at":2465,"payload":2472},{"name":1230},{"ref":1412},{"type":1211,"repo":2474,"created_at":2465,"payload":2475},{"name":1230},{"ref":1675},{"type":1211,"repo":2477,"created_at":2478,"payload":2479},{"name":1230},"2026-09-28T11:04:03Z",{"ref":1675},{"type":1211,"repo":2481,"created_at":2482,"payload":2483},{"name":1230},"2026-09-28T10:47:46Z",{"ref":1528},{"type":1211,"repo":2485,"created_at":2486,"payload":2487},{"name":1230},"2026-09-28T10:47:45Z",{"ref":1467},{"type":1211,"repo":2489,"created_at":2461,"payload":2490},{"name":1230},{"ref":1675},{"type":1211,"repo":2492,"created_at":2461,"payload":2493},{"name":1230},{"ref":1412},{"type":1211,"repo":2495,"created_at":2496,"payload":2497},{"name":1230},"2026-09-28T11:24:33Z",{"ref":1233},{"type":1211,"repo":2499,"created_at":2496,"payload":2500},{"name":1230},{"ref":1467},{"type":1235,"repo":2502,"created_at":2503,"payload":2504},{"name":1230},"2026-09-28T10:12:27Z",{"ref":2505,"ref_type":1240},"feature\u002Fdruxt-module-1.3",{"type":1211,"repo":2507,"created_at":2508,"payload":2509},{"name":1230},"2026-09-28T11:06:29Z",{"ref":1519},{"type":1211,"repo":2511,"created_at":2512,"payload":2513},{"name":1243},"2026-09-28T02:57:38Z",{"ref":1302},{"type":1211,"repo":2515,"created_at":2376,"payload":2516},{"name":1230},{"ref":1233},{"type":1211,"repo":2518,"created_at":2478,"payload":2519},{"name":1230},{"ref":1519},{"type":1211,"repo":2521,"created_at":2478,"payload":2522},{"name":1230},{"ref":1412},{"type":1203,"repo":2524,"created_at":2525,"payload":2526},{"name":1230},"2026-09-28T10:48:09Z",{"action":913,"pull_request":2527},{"number":1736},{"type":1211,"repo":2529,"created_at":2530,"payload":2531},{"name":1230},"2026-09-28T10:47:47Z",{"ref":1675},{"type":1211,"repo":2533,"created_at":2530,"payload":2534},{"name":1230},{"ref":1519},{"type":1235,"repo":2536,"created_at":2482,"payload":2537},{"name":1230},{"ref":2538,"ref_type":1240},"feature\u002Frepo-standards",{"type":1211,"repo":2540,"created_at":2482,"payload":2541},{"name":1230},{"ref":1233},{"type":1211,"repo":2543,"created_at":2486,"payload":2544},{"name":1230},{"ref":1412},{"type":1203,"repo":2546,"created_at":2547,"payload":2548},{"name":1230},"2026-09-28T10:13:18Z",{"action":913,"pull_request":2549},{"number":2550},505,1790908952639]