Releases: remix-run/remix
v1.7.4
What Changed
Patch Changes
-
You can now infer the type of the
.data
property of fetchers from youraction
andloader
functions. This works similarly to our type inference ofuseLoaderData
by providing the type of theaction
orloader
function at theuseFetcher
call site.export async function loader(args: LoaderArgs) { return json({ user: { name: "Chance", twitter: "@chancethedev", age: 36, }, }); } function SomeComponent() { let fetcher = useFetcher<typeof loader>(); if (fetcher.data) { let userName = fetcher.data.user.name; // string let userAge = fetcher.data.user.age; // number } }
-
Fixed a bug in
<Form>
that prevented the correct method from being called with non-POST
submissions
Changes by package
New Contributors
- @michaelhelvey made their first contribution in #4392
- @maxschwarzmueller made their first contribution in #4413
Full Changelog: v1.7.3...v1.7.4
v1.7.3
What Changed
Patch Changes
-
<Form />
now respects theformMethod
attribute set on the submitter element (#4053)<Form> <button type="submit">GET request</button> <button type="submit" formMethod="post"> POST request </button> </Form>
-
Assets referenced in CSS files are now hashed and copied to the
assetsBuildDirectory
(#4130).Before this change, a CSS declaration like
background: url('./relative-path/image.png')
that references the file./relative-path/image.png
will not copy that file to the build directory. This can be a problem if you use a custom build directory, or when dealing with third-party stylesheets innode_modules
that reference their own relative files. -
We updated the
@remix-run/web-fetch
dependency for@remix-run/node
(#4277). This fixes issues with{Request | Response}.clone()
throwing when body isnull
. This update also adds additional Node.js-specific types tofetch()
to support the use ofagent
fromhttp
andhttps
. -
Added support for setting
moduleResolution
tonode
,node16
ornodenext
intsconfig.json
(#4034) -
Added resources imported only by resource routes to
assetsBuildDirectory
(#3841)
Changes by package
New Contributors
- @markdalgleish made their first contribution in #4173
- @wtlin1228 made their first contribution in #4224
- @ryanjames1729 made their first contribution in #4241
- @runofthemill made their first contribution in #4268
- @kamtugeza made their first contribution in #4041
- @freeman made their first contribution in #4159
- @johnmberger made their first contribution in #4329
- @kevlened made their first contribution in #4053
- @KingSora made their first contribution in #4130
Full Changelog: v1.7.2...v1.7.3
v1.7.2
What's Changed
Bug Fixes
- Preserve
?index
for fetcher get submissions to index routes (#4238) - Fix dependency conflicts with
type-fest
(87642b71b
) - Update ESLint and plugin dependencies (
e4ec81c77
) - Flush Node streams to address issues with libraries like
compression
that rely on chunk flushing (#4235)
Changes by package
Full Changelog: v1.7.1...v1.7.2
v1.7.1
What's Changed
Bug fixes 🐛
- Ensured that requests are properly aborted on closing of a
Response
instead ofRequest
in all Node adapters (#3626) - Locked the dependency on
react-router-dom
to version 6.3.0 instead of using a semver range (#4203), as installingreact-router-dom@6.4.0
will cause compatibility issues - Fixed a bug with
GET
form submissions to ensure they replace the current search params, which tracks with the browser's behavior (#4046)
Changes by package
@remix-run/architect
@remix-run/express
@remix-run/netlify
@remix-run/react
@remix-run/server-runtime
@remix-run/vercel
New Contributors
- @scottybrown made their first contribution in #3949
- @rkulinski made their first contribution in #4003
- @jrf0110 made their first contribution in #4050
- @jwnx made their first contribution in #3936
- @shairez made their first contribution in #3962
- @jmorel88 made their first contribution in #4066
- @willhack made their first contribution in #4147
- @riencoertjens made their first contribution in #4158
- @arjunyel made their first contribution in #4133
- @Deanmv made their first contribution in #4170
- @leifarriens made their first contribution in #4181
Full Changelog: v1.7.0...v1.7.1
v1.7.0
What's Changed
✨ Features
-
We removed our compiler's React shim in favor of esbuild's new automatic JSX transformation.
There are no code changes required on your end, but by using the new transform we can prevent duplicate React imports from appearing in your build.
The automatic JSX transform was introduced in React 17, and it allows you to write your JSX code without ever needing to import React. This means that compilers need to map JSX to
React.createElement
for you.Because esbuild previously didn't support this feature, we implemented a "shim" for the import to get the same affect. This unfortunately has caused problems with some external libraries, resulting in React being declared multiple times. (#2987)
You still need to import modules from React that you use directly in your code (
useState
,useEffect
, etc.). But if your component only needs the React import for JSX, you can safely omit it without worrying about duplicate imports. -
The
MetaFunction
type can now inferdata
andparentsData
types from route loaders.For example, if this meta function is exported from
app/routes/sales/customers/$customerId
:const meta: MetaFunction< typeof loader, // this will infer our type for `data` { root: RootLoader; // exported from the root route "routes/sales": SalesLoader; // exported from the sales route "routes/sales/customers": CustomersLoader; // exported from the sales/customers route } > = ({ data, parentsData }) => { /// };
The meta function can be strongly typed by exposing each parent route's loader type:
// app/root.tsx const loader = () => { return json({ hello: "world" } as const); }; export type Loader = typeof loader; // app/routes/sales.tsx const loader = () => { return json({ salesCount: 1074 }); }; export type Loader = typeof loader; // app/routes/sales/customers.tsx const loader = () => { return json({ customerCount: 74 }); }; export type Loader = typeof loader; // app/routes/sales/customers/$customersId.tsx import type { Loader as RootLoader } from "~/root"; import type { Loader as SalesLoader } from "~/routes/sales"; import type { Loader as CustomersLoader } from "~/routes/sales/customers"; const loader = () => { return json({ name: "Customer name" }); }; const meta: MetaFunction< typeof loader, { root: RootLoader; "routes/sales": SalesLoader; "routes/sales/customers": CustomersLoader; } > = ({ data, parentsData }) => { const { name } = data; // ^? string const { customerCount } = parentsData["routes/sales/customers"]; // ^? number const { salesCount } = parentsData["routes/sales"]; // ^? number const { hello } = parentsData["root"]; // ^? "world" };
-
Each runtime package now exports a new type:
SerializeFrom
. This is used to infer the JSON-serialized return type of loaders and actions.type MyLoaderData = SerializeFrom<typeof loader>; type MyActionData = SerializeFrom<typeof action>;
Changes by package
@remix-run/cloudflare
@remix-run/deno
@remix-run/dev
@remix-run/node
@remix-run/react
@remix-run/serve
@remix-run/server-runtime
New Contributors
- @philandstuff made their first contribution in #3939
- @maxprilutskiy made their first contribution in #3944
- @willin made their first contribution in #3957
- @joelazar made their first contribution in #3902
- @arnaudambro made their first contribution in #3953
- @redabacha made their first contribution in #3889
- @andreiduca made their first contribution in #3985
- @justinwaite made their first contribution in #3989
- @n8agrin made their first contribution in #4001
Full Changelog: v1.6.8...v1.7.0
v1.6.8
What's Changed
💅 Enhancements
- You can now use
.mjs
or.cjs
file extensions forremix.config
(#3675) - We added support for importing
.sql
files as text content (#3190) - We made some optimizations in our compiler to make MDX builds deterministic (and a little faster!) (#3966)
- Your load context is now type safe! The
AppLoadContext
type is now an an interface mappingstring
tounknown
(#1876). This allows you to extend it via module augmentation:declare module "@remix-run/server-runtime" { interface AppLoadContext { // add custom properties here! } }
- We added a subscribe method to the transition manager, which allows subscribing and unsubscribing for React 18 strict mode compliance (#3964)
🐛 Bug fixes
- Previously, if an
action
was omitted from<Form>
oruseFormAction
, the action value would default to"."
. This is incorrect, as"."
should resolve based on the current path, but an empty action resolves relative to the current URL (including the search and hash values). We've fixed this to differentiate between the two, meaning that the resolved action will preserve the full URL. (#3697) - Fixed a few types to work more seamlessly with changes in
@types/react@18
(#3917)
Changes by package
New Contributors
- @DanielFGray made their first contribution in #1876
- @julio-lemos made their first contribution in #3874
- @nrako made their first contribution in #3611
Full Changelog: v1.6.7...v1.6.8
v1.6.7
What's Changed
-
Patched a syntax error in
@remix-run/dev
to ensurecreate-remix
runs smoothly on Node 14 -
Fix inferred types for
useLoaderData
anduseActionData
to preservenull
value types in@remix-run/react
.Previously,
null
types were being replaced bynever
due to our usage ofNonNullable
inUndefinedOptionals
. Properties that aren't unions withundefined
are now kept as-is, while properties that do includeundefined
are still made optional, but only removeundefined
from the property type whereasNonNullable
also removednull
types.
Changes by package
Full Changelog: v1.6.6...v1.6.7
v1.6.6
What's Changed
-
We've added support for exporting a
links
function from.mdx
routes (#3801). This is leveraging the fact that MDX (which we use to parse your markdown routes) allows you to declare and export anything:--- meta: title: Welcome to the site description: Hello, World! --- export const links = () => [ { rel: "stylesheet", href: "/welcome.css", media: "(prefers-reduced-motion: no-preference)", }, ]; # My Page This is **markdown** with links 🎉
-
Fixed a few type-related bugs in
@remix-run/react
.
Changes by package
New Contributors
- @vorcigernix made their first contribution in #3718
- @TAGraves made their first contribution in #3763
- @nickytonline made their first contribution in #3754
- @Synvox made their first contribution in #3767
- @Drew-Daniels made their first contribution in #3770
- @jasonadelia made their first contribution in #3788
- @plondon made their first contribution in #3799
- @esamattis made their first contribution in #3797
- @runmoore made their first contribution in #3798
- @awthwathje made their first contribution in #3804
- @alextes made their first contribution in #3813
- @gst4r made their first contribution in #3433
- @dvargas92495 made their first contribution in #2803
- @chipit24 made their first contribution in #3823
- @vincecao made their first contribution in #3834
- @itsMapleLeaf made their first contribution in #3766
Full Changelog: v1.6.5...v1.6.6
v1.6.5
What's Changed
Enhanced types to allow inference of loader
/ action
data
We enhanced the type signatures of loader
/action
and useLoaderData
/useActionData
to make it possible to infer the data type from return type of its related server function.
To enable this feature, you will need to use the LoaderArgs
type from your Remix runtime package instead of typing the function directly:
- import type { LoaderFunction } from "@remix-run/[runtime]";
+ import type { LoaderArgs } from "@remix-run/[runtime]";
- export const loader: LoaderFunction = async (args) => {
- return json<LoaderData>(data);
- }
+ export async function loader(args: LoaderArgs) {
+ return json(data);
+ }
Then you can infer the loader data by using typeof loader
as the type variable in useLoaderData
:
- let data = useLoaderData() as LoaderData;
+ let data = useLoaderData<typeof loader>();
The API above is exactly the same for your route action
and useActionData
via the ActionArgs
type.
With this change you no longer need to manually define a LoaderData
type (huge time and typo saver!), and we serialize all values so that useLoaderData
can't return types that are impossible over the network, such as Date
objects or functions.
See the discussions in #1254 and #3276 for more context.
All changes by package
@remix-run/cloudflare
@remix-run/cloudflare-workers
@remix-run/deno
@remix-run/dev
@remix-run/eslint-config
@remix-run/node
@remix-run/react
@remix-run/server-runtime
@remix-run/vercel
New Contributors
- @ronnylt made their first contribution in #3681
- @vmosyaykin made their first contribution in #3698
- @garand made their first contribution in #859
- @kiancross made their first contribution in #3716
Full Changelog: v1.6.4...v1.6.5
v1.6.4
What's Changed
🐛 Bug fixes
- Fixed a regression with Node v18.3 by making the detection of IPv4 addresses more durable in
@remix-run/serve
and@remix-run/dev
(#3602) - Fix Yarn PnP resolution for empty modules (#3633)
💅 Enhancements
- Add
watchPaths
option forremix.config
. This allows you to define custom directories to watch while runningremix dev
(#3188).
New Contributors
- @justsml made their first contribution in #3602
- @christophertrudel made their first contribution in #3188
- @manan30 made their first contribution in #3631
- @juliaqiuxy made their first contribution in #3598
- @lensbart made their first contribution in #3595
- @federicoestevez made their first contribution in #3644
- @shashankboosi made their first contribution in #3642
- @justinsalasdev made their first contribution in #3547
- @guatedude2 made their first contribution in #3637
Full Changelog: v1.6.3...v1.6.4